使用dwr3.0实现服务端向浏览器做消息推送,做滚动评论或弹幕效果,而且根据视频id做推送消息拦截功能

来源:互联网 发布:淘宝定制的好不好 编辑:程序博客网 时间:2024/05/21 17:41

最近项目要实现视频播放时做弹幕和评论滚动,使用flash做sockt编程不会,就想到使用服务器消息推送做,翻找资料发现使用html5的websocket可以实现,但是ie8是不支持websocket的,最终确定使用dwr3做消息推送,普通的dwr3做消息推送会把消息推送到所有打开的页面,这样针对某一个视频的评论就会弹出到其他的视频中去,实现每个视频弹出各自的评论,就需要做dwr3的消息推送做过滤处理,经过一天的研究终于搞定了

贴出完整的代码demo

1 使用dwr3的web.xml的配置

<servlet-name>dwr-invoker</servlet-name>
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    
        <init-param>
         <param-name>fileUploadMaxBytes</param-name>
         <param-value>25000</param-value>
        </init-param>
        
        <!-- This should NEVER be present in live -->
        <init-param>
          <param-name>debug</param-name>
          <param-value>true</param-value>
        </init-param>
      
        <init-param>
          <param-name>accessLogLevel</param-name>
          <param-value>runtimeexception</param-value>
        </init-param>
        
        <!-- Remove this unless you want to use active reverse ajax -->
        <init-param>
          <param-name>activeReverseAjaxEnabled</param-name>
          <param-value>true</param-value>
        </init-param>
    
        <!-- By default DWR creates application scope objects when they are first
        used. This creates them when the app-server is started -->
        <init-param>
          <param-name>initApplicationScopeCreatorsAtStartup</param-name>
          <param-value>true</param-value>
        </init-param>
    
        <!-- WARNING: allowing JSON-RPC connections bypasses much of the security
        protection that DWR gives you. Take this out if security is important -->
        <init-param>
          <param-name>jsonRpcEnabled</param-name>
          <param-value>true</param-value>
        </init-param>
    
        <!-- WARNING: allowing JSONP connections bypasses much of the security
        protection that DWR gives you. Take this out if security is important -->
        <init-param>
          <param-name>jsonpEnabled</param-name>
          <param-value>true</param-value>
        </init-param>
    
        <!-- data: URLs are good for small images, but are slower, and could OOM for
        larger images. Leave this out (or keep 'false') for anything but small images -->
        <init-param>
          <param-name>preferDataUrlSchema</param-name>
          <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
  </servlet>

2 dwr.ml的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">
<dwr>
    <allow>
        <create creator="new" scope="application">
          <param name="class" value="com.example.dwr.reverseajax.JavascriptChat"/>
        </create>
        <create creator="new" scope="application">
          <param name="class" value="com.example.dwr.reverseajax.JavaChat"/>
        </create>
        <convert converter="bean" match="com.example.dwr.reverseajax.Message"/>
   </allow>
</dwr>
3 项目中使用了strust2,需要配置一个属性以便strust2放过dwr的请求

<constant name="struts.action.excludePattern" value="/dwr/*" />

4 java代码

(1)用于接收消息和处理消息的java文件


package com.example.dwr.reverseajax;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.directwebremoting.ScriptSessions;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;

import com.jovision.modelBean.LoginInfo;

/**
 *
 * @author liuhailong
 *
 */
public class JavascriptChat
{
   
    public void addMessage(String text,final String oid)
    {
        String mess = text;
        WebContext wc = WebContextFactory.get();
        wc.getScriptSession().setAttribute("oid", oid);
        LoginInfo loginInfo = (LoginInfo) wc.getSession().getAttribute("loginInfo");
        if (loginInfo != null) {
            mess = loginInfo.getAccount() + "说:" + mess;
        }else{
            mess = "游客说:" + mess;
        }
        if(!map.containsKey(oid)){
            LinkedList<Message> list = new LinkedList<Message>();
            map.put(oid, list);
        }
        final LinkedList<Message> messages = map.get(oid);
        if (text != null && text.trim().length() > 0)
        {
            messages.addFirst(new Message(mess));
            while (messages.size() > 10)
            {
                messages.removeLast();
            }
        }
        //过滤器
        ScriptSessionFilter filter = new ScriptSessionFilter() {
            public boolean match(ScriptSession scriptSession) {
                 String tag = (String)scriptSession.getAttribute("oid");
                 return oid.equals(tag);
            }
        };
        //执行方法
        Runnable run = new Runnable(){
              public void run() {
                  ScriptSessions.addFunctionCall("receiveMessages", messages);
             }
        };
        //发送消息
        Browser.withCurrentPageFiltered(filter,run);
    }

    /*
     * 存储消息的map对象
     */
    private final Map<String,LinkedList<Message>> map = new HashMap<String,LinkedList<Message>>();
    
}

(2)消息对象

package com.example.dwr.reverseajax;

/**
 * @author liuhailong
 */
public class Message
{
    /**
     * @param newtext the new message text
     */
    public Message(String newtext)
    {
        text = newtext;

        if (text.length() > 256)
        {
            text = text.substring(0, 256);
        }
    }

    /**
     * @return the message id
     */
    public long getId()
    {
        return id;
    }

    /**
     * @return the message itself
     */
    public String getText()
    {
        return text;
    }

    /**
     * When the message was created
     */
    private long id = System.currentTimeMillis();

    /**
     * The text of the message
     */
    private String text;
}

5 用于消息弹出的jsp页面

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cn" lang="cn">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Simple DWR Chat Version 3.0</title>
  <script type='text/javascript' src='../dwr/engine.js'> </script>
  <script type='text/javascript' src='../dwr/interface/JavascriptChat.js'> </script>
  <script type='text/javascript' src='../dwr/util.js'> </script>
  <script type="text/javascript" src='javascript-chat.js'> </script>
</head>
<body onload="init();Tabs.init('tabList', 'tabContents');">
<div id="tabContents">
  <div id="demoDiv">
    <div id="chatlog" style="height:400px;overflow-y:auto"></div>
    <p>
          评论:
      <input id="text" onkeypress="dwr.util.onReturn(event, sendMessage)"/>
      <input type="button" value="发送" onclick="sendMessage()"/>
    </p>
  </div>
</div>
</body>
</html>

6 使用的javescript脚本文件代码

function init() {
  dwr.engine.setActiveReverseAjax(true);
}

function sendMessage() {
  var text = dwr.util.getValue("text");
  var oid = window.parent.document.getElementById('oid').value;
  dwr.util.setValue("text", "");
  JavascriptChat.addMessage(text,oid);
}

function receiveMessages(messages) {
  var chatlog = "";
  for (var data in messages) {
    chatlog = "<div>" + dwr.util.escapeHtml(messages[data].text) + "</div>" + chatlog;
  }
  dwr.util.setValue("chatlog", chatlog, { escapeHtml:false });
}
做该功能时观看了网上一位比较了解dwr的人员的博客 网页地址:http://www.kankanews.com/ICkengine/archives/82552.shtml点击打开链接
使用这种方式能够实现消息弹幕 缺点是比较消耗服务器资源,希望还有更好的办法提供

0 0
原创粉丝点击