推送技术产生的原因
- Ajax应用中存在一个致命的缺陷无法满足传统桌面系统的需求
- 服务器端需要向客户端主动发送消息
推送技术的应用场景
- 网页邮箱新邮件提醒
- 网页聊天
- 微信签到墙(现场版)
客户端得到通知的方式
定时刷新
缺点:
- 整个页面的刷新,给用户带来的体验非常不好。
- 频繁的刷新,给服务器端带来的压力非常大,造成非常大的带宽的浪费。
Ajax轮询
缺点:
- 实时性。向服务器端查询的间隔时间令人纠结,因为性能和即时性造成了严重的反比关系。
- 频繁刷新,给服务器带来的压力。
优点:
- 不需要服务器端的配置。
- 可以降低带宽的负荷。(Ajax优势就在于异步加载数据)
Comet长连接
由Browser端发起请求,Server端以一种特别慢的方式返回响应。
优点:
- 实时性比较好。
- 性能还不错。
缺点:
等待时间比较长,长期占用长连接资源。
- Flash XML Socket
缺点:
- Flash必须提供XML Socket类
JavaScript、Flash必须紧密结合(JavaScript可以直接调用Flash提供的接口)。
- Java Applet套接口
客户端使用Java.NET的Socket类建立与服务器端套接口的一个连接。
- Java Applet套接口
缺点:
- 需要在客户端安装Java虚拟机。
Dwr介绍
一个基于Ajax的框架,可以动态把Java类生成JavaScript,从而让客户端JavaScript通过DWR访问Java程序。
运行原理:
- 服务器启动的时候,读取dwr.xml生产xxx.js
- 客户端js触发xxx.js中的方法
- web容器接收请求创建实例
重要概念
- scriptSession
每次访问服务器都会创建一个scriptSession
Dwr3.0:
Collection<ScriptSession> sessions = Browser.getTargetSession();
Dwr2.x:
Collection pages = webContext.getScriptSessionsByPage("/xxx.jsp")
Dwr配置详解
- pom.xml 配置maven依赖
<dependency>
<groupId>org.directwebremoting</groupId>
<artifactId>dwr</artifactId>
<version>3.0.2-RELEASE</version>
</dependency>
- 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>
- 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>
- 创建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>
- 创建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类的名字。
- 创建推送方法(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);//向客户端推送消息
}
}