服务器端推送技术浅析

推送技术产生的原因

  1. Ajax应用中存在一个致命的缺陷无法满足传统桌面系统的需求
  2. 服务器端需要向客户端主动发送消息

推送技术的应用场景

  1. 网页邮箱新邮件提醒
  2. 网页聊天
  3. 微信签到墙(现场版)

客户端得到通知的方式

  1. 定时刷新

    缺点:

    • 整个页面的刷新,给用户带来的体验非常不好。
    • 频繁的刷新,给服务器端带来的压力非常大,造成非常大的带宽的浪费。
  2. Ajax轮询

    缺点:

    • 实时性。向服务器端查询的间隔时间令人纠结,因为性能和即时性造成了严重的反比关系。
    • 频繁刷新,给服务器带来的压力。

    优点:

    • 不需要服务器端的配置。
    • 可以降低带宽的负荷。(Ajax优势就在于异步加载数据)
  3. Comet长连接

由Browser端发起请求,Server端以一种特别慢的方式返回响应。

优点:

  • 实时性比较好。
  • 性能还不错。

缺点:

  • 等待时间比较长,长期占用长连接资源。

    1. Flash XML Socket

    缺点:

    • Flash必须提供XML Socket类
    • JavaScript、Flash必须紧密结合(JavaScript可以直接调用Flash提供的接口)。

      1. Java Applet套接口

      客户端使用Java.NET的Socket类建立与服务器端套接口的一个连接。

缺点:

  • 需要在客户端安装Java虚拟机。

Dwr介绍

一个基于Ajax的框架,可以动态把Java类生成JavaScript,从而让客户端JavaScript通过DWR访问Java程序。

运行原理:

  1. 服务器启动的时候,读取dwr.xml生产xxx.js
  2. 客户端js触发xxx.js中的方法
  3. web容器接收请求创建实例

重要概念

  • scriptSession

每次访问服务器都会创建一个scriptSession

Dwr3.0:
Collection<ScriptSession> sessions = Browser.getTargetSession();

Dwr2.x:
Collection pages = webContext.getScriptSessionsByPage("/xxx.jsp")

Dwr配置详解

  1. pom.xml 配置maven依赖
<dependency>
    <groupId>org.directwebremoting</groupId>
    <artifactId>dwr</artifactId>
    <version>3.0.2-RELEASE</version>
</dependency>
  1. web.xml 配置
<servlet>
    <servlet-name>dwr.invoker</servlet-name>
    <!-- 2.x版本 -->
    <!-- <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> -->

    <!-- 3.x版本 -->
    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>

    <!-- 使用debug模式 -->
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>

    <!-- 使用服务器推技术(翻转AJAX) -->
    <init-param>
        <param-name>activeReverseAjaxEnabled</param-name>
        <param-value>true</param-value>
    </init-param>

    <!-- 使能够从其他域进行请求 true:开启;false: 关闭 -->
    <init-param>
        <param-name>crossDomainSessionSecurity</param-name>
        <param-value>false</param-value>
    </init-param>

    <!-- 允许远程js -->
    <init-param>
        <param-name>allowScriptTagRemoting</param-name>
        <param-value>true</param-value>
    </init-param>

    <load-on-startup>1</load-on-startup> 

</servlet>

<!-- 映射路径 -->
<servlet-mapping>
    <servlet-name>dwr.invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
  1. dwr.xml配置
<?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" javascript="service">  
              <param name="class" value="lxd.demo.dwr"/>  
          </create>  
     </allow>  
</dwr>
  1. 创建JSP页面
<%@page contentType="text/html" pageEncoding="UTF-8"%>  
<!DOCTYPE html>  
<html>  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
        <title>JSP Page</title>  
        <script src="<%=request.getContextPath()%>/dwr/engine.js"></script>  
        <script src="<%=request.getContextPath()%>/dwr/interface/Hello.js"></script>  

        <script>  
            Hello.sayHello("张三");  
        </script>  
    </head>  
    <body>  
        <h1>Hello World!</h1>  
    </body>  
</html>  
  1. 创建JAVA页面
package lxd.demo.dwr;  

/** 
 * 
 * @author lxd 
 */  
public class Hello {  
    public String sayHello(String name){  
        System.out.println("hello "+name);  
        return "hello "+name;  
    }  
}

=====================================================================

4.创建页面

<%@page contentType="text/html" pageEncoding="UTF-8"%>  
<!DOCTYPE html>  
<html>  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
        <title>JSP Page</title>  
        <script type="text/javascript" src="<%=request.getContextPath()%>/dwr/util.js"></script>
        <script type="text/javascript" src="<%=request.getContextPath()%>/dwr/engine.js"></script>  
        <script type="text/javascript" src="<%=request.getContextPath()%>/dwr/interface/SendPushService.js"></script>  
        <script type="text/javascript" src="<%=request.getContextPath()%>/lib/jquery-1.7.1.min.js"></script> 

        <script>  
            <!--function firstDwr() {
                service.sayHello("Hello Dwr", callBackHello);
            }  

            function callBackHello(data) {
                alert(data);
            }-->
            $(document).ready(function() {
                dwr.engine.setActiveReverseAjax(true);

                $("#sign").click(function() {
                    SendPushService.send($("msg").val());
                });
            });

            function callback(msg) {
                $("#ul").html($("#ul").html() + "</br>" + msg);
            }
        </script>  
    </head>  
    <body>  
        <!--<input type="button" name="button" value="测试Dwr" onClick="firstDwr()">--> 
        <ul id="ul" style="color:red;font-size:60px;"></ul>
        <input type="text" name="msg" id="msg"> size="30" style="height:60px;font-size:35px;"/>
        <input type="button" id="sign" value="发布信息"/>
    </body>  
</html>

上面引入的js文件,util.js和engine.js是固定的,service.js是我们定义的Java类的名字。

  1. 创建推送方法(Java类)
public class SendPushService {

    //发送消息
    public void send(String msg) {
        System.out.println("===调用了send方法===");
        ScriptBuffer scriptBuffer = new ScriptBuffer();//构造js脚本
        WebContext webContext = WebContextFactory.get();
        //ScriptSession myScSession = webContext.getScriptSession();
        Collection sessions = webContext.getAllScriptSessions();
        scriptBuffer.appendScript("callback(");
        scriptBuffer.appendData(msg);
        scriptBuffer.appendScript(")");
        Util util = new Util(sessions);
        //Util util = new Util(myScSession);
        util.addScript(scriptBuffer);//向客户端推送消息
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值