一、comet基本概念
1.comet是一个用于描述客户端和服务器之间交互的术语,即使用长期保持的http连接来在连接保持畅通的情况下支持客户端和服务器间的事件驱动的通信。
2.传统的web系统的工作流程是客户端发出请求,服务器端进行响应,而comet则是在现有技术的基础上,实现服务器数据、事件等快速push到客户端,所以会出现一个术语”服务器推“技术。
二、push实现方式
1.原理:
利用jsp/servel技术,在不关闭http流的情况下push数据到客户端浏览器;
2.实现:
基于ajax的长轮询(long-polling)方式
ajax的出现使得javascript可以调用xmlhttprequest对象发出http请求,javascript响应处理函数根据服务器返回的信息对html页面的显示进行更新。使用ajax实现“服务器推”与传统的ajax应用不同之处在于:
1)、服务器端会阻塞请求直到有数据传递或超时才返回。
2)、客户端 javascript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
3)、当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重 新建立连接,客户端会一次把当前服务器端所有的信息取回。
Pushlet实例
一、首先建立一个web工程pushlet,将pushlet.jar放到lib目录中,引入到工程。并且将pushlet.properties和sources.properties两个文件拷贝到WEB-INF目录中去。工程的目录结构如图示
我们一般只需要对sources.properties进行修改即可,创建的消息源必须在这个文件中进行配置。消息源需要实现EventSource接口
二、配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 注意,缺省不需要修改<url-pattern>/pushlet.srv</url-pattern>,如果修改, 需要在对应的js文件中也要修改。pushlt缺省就是通过pushlet.srv触发servlet的。 --> <servlet> <servlet-name>pushlet</servlet-name> <servlet-class> nl.justobjects.pushlet.servlet.Pushlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>pushlet</servlet-name> <url-pattern>/pushlet.srv</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
三、看一下index.jsp这个文件的内容
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>HelloWorld</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script type="text/javascript" src="ajax-pushlet-client.js"></script> <script type="text/javascript"> //对pushlet的初始化,触发web.xml中的servlet。 PL._init(); //这里的监听的主题,必须在sources.properties中配置的对象中声明这个主题。 //sources.properties配置着事件源(EventSources),在服务器启动时会自动激活。 //可以通过服务器的启动记录查看得到。可以将这个文件放到WEB-INF目录下面或者classess目录下面都可以。 PL.joinListen('/linjiqin/hw'); function onData(event) { alert(event.get("hw")); } </script> </head> <body> </body> </html>
四、修改sources.properties文件
source1=nl.justobjects.pushlet.test.TestEventPullSources$TemperatureEventPullSource source2=nl.justobjects.pushlet.test.TestEventPullSources$SystemStatusEventPullSource source3=nl.justobjects.pushlet.test.TestEventPullSources$PushletStatusEventPullSource source4=nl.justobjects.pushlet.test.TestEventPullSources$AEXStocksEventPullSource source5=nl.justobjects.pushlet.test.TestEventPullSources$WebPresentationEventPullSource source6=nl.justobjects.pushlet.test.TestEventPullSources$PingEventPullSource #source1~source6是系统缺省自带的,source7是我自己配置的,并且在index.jsp中的脚本中, #配置的/linjiqin/hw是和这儿是对应的。具体是这样的。HwPlushlet是com.ljq.test.HelloWorldPlushlet对象的一个内部类, #并且继承EventPullSource接口。 source7=com.ljq.test.HelloWorldPlushlet
五、核心代码HelloWorldPlushlet
package com.ljq.test; import java.io.Serializable; import nl.justobjects.pushlet.core.Event; import nl.justobjects.pushlet.core.EventPullSource; @SuppressWarnings("serial") public class HelloWorldPlushlet extends EventPullSource implements Serializable { /** * 设置休眠时间 */ @Override protected long getSleepTime() { return 1000; } /** * 创建事件 * * 业务部分写在pullEvent()方法中,这个方法会被定时调用。 */ @Override protected Event pullEvent() { Event event = Event.createDataEvent("/linjiqin/hw"); event.setField("hw", "HelloWorld!!!!"); return event; } }
这样这个基本的例子就OK了,运行一下,看看吧。
访问http://localhost:8083/pushletprj 会定时弹出alert窗口,窗口的内容如下图:
如果这个页面关闭了,服务器会自动取消订阅,和移除对应的session信息。下面是我关闭页面后,服务器端的输出信息,如图: