java comet demo_用java实现comet,基于 HTTP长连接的实现,用于从服务端实时发送信息到客户端...

http://homelink.javaeye.com/blog/293328#comments

参考文档 http://www.ibm.com/developerworks/cn/web/wa-lo-comet/

comet是HTTP长连接,就是在HTTP发送请求时,服务器不立刻发送响应信息给客户端,

而是保持着连接,等待一定情况发生后才把数据发送回去给客户端。所以用comet可以实现服务器端的数据实时地发送给客户端。

本文主要是用java和js来简单地实现comet,最后附上源码和使用例子。

在客户端用XMLRequest发送请求到服务器,在服务器端用一个servlet来接收XMLRequest的请求,当接收到请

求时,并不立刻响应客户端,而是把该servlet线程阻塞,等到一定事件发生后,再响应客户端。当客户端接收到服务端的响应后,调用自定义的回调函数来

处理服务器发送回来的数据,处理完成后,再发送一个XMLRequest请求到服务端,这样循环下去,就可以实现数据的实时更新,又不必要在客户端不断地

轮循(polling)。

利用该comet的实现(以后简称为keeper)时,只要在客户端注册事件和写一个处理返回数据的回调函数,然后在服务端实现

keeper中的EventListener接口,调用Controller.action(eventListener,eventType)就可以

了。

keeper分成两大部分,第一部分为客户端的javascript,第二部分是服务端的servlet和事件处理。

一.客户端

建立一个XMLRequest对象池,每发送一次请求,从对象池中取一个XMLRequest对象,如果没有可用的对象,则创建一

个,把它加入到对象池中。这部分的代码来自于网络。

为了使用方便,再添加一些方法,用来注册事件。这样只要调用注册函数来注册事件,并且把回调函数传给注册事件函数就行了,处理数据

的事情,交给回调函数,并由用户来实现。

keeper为了方便使用,把客户端的javascript代码集成在servlet中,当配置好keeper的servlet,

启动HTTP服务器时,keeper会根据用户的配置,在相应的目录下生成客户端的javascript代码。

二.服务端

服务端的servlet初始化时,根据配置来生成相应的客户端javascript代码。

servlet的入口由keeper.servlet.Keeper.java中的doGet进入。在Keeper的doGet

中,从请求中获取用户注册事件的名称(字符串类型),然后根据事件的名称,构造一个事件(Event类型),再把它注册到NameRegister中,注

册完成后,该servlet线程调用wait(),把自已停止。等待该servlet线程被唤醒后,从Event中调用事件的EventListener

接口的process(request,response)来处理客户端的请求。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String eventName = request.getParameter("event");

NameRegister reg = NameRegister.getInstance();

Event event = null;

try {

event = reg.getEvent(eventName);

if(event == null) {

event = new Event(eventName,this);

reg.registeEvent(eventName, event);

}

if(event.getServlet() == null) {

event.setServlet(this);

}

} catch (RegistException e1) {

e1.printStackTrace();

}

synchronized(this) {

while(!event.isProcess()) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

EventListener listener = event.getListener();

if(listener != null) {

listener.process(request,response);

}

}

在服务端处理事件时,调用了keeper.control.Controller中的静态方法

action(EventListener listener,String eventName)来处理。如下所示。

public static boolean action(EventListener listener,String eventName){

NameRegister reg = NameRegister.getInstance();

HttpServlet servlet = null;

Event e = null;

try {

e = reg.getEvent(eventName,true);

if(e == null) {

return false;

}

e.setListener(listener);

servlet = e.getServlet();

e.setProcess(true);

synchronized(servlet) {

servlet.notifyAll();

}

} catch (RegistException ex) {

ex.printStackTrace();

}

if(servlet != null && e != null) {

e = null;

return true;

} else {

return false;

}

}

下面开始用keeper来写一个简单的网页聊天程序和基于服务端的时间。

1.客户端设置

注册两个事件,一个用于是时间事件,一个是消息事件。同时还要写两个回调函数,用于处理服务

端返回的时间和聊天消息。如下所于:

Keeper.addListener('timer',showTime);//注册时间事件

function showTime(obj){ //时间处理回调函数

var sp = document.getElementById("dateTime");

if(sp){

sp.innerHTML = obj.responseText;

}

}

function startOrStop(obj){

var btn = document.getElementById("controlBtn")

btn.value=obj.responseText;

}

Keeper.addListener('msg',showMsg,"GBK");//注册消息事

件,最后一个参数是

//字符串编码

function showMsg(obj){//处理消息的回调函数

var msg = document.getElementById("msg");

if(msg){

msg.value = obj.responseText+""n"+msg.value;

}

}

function sendMsg() {

var msg = document.getElementById("sendMsg");

if(msg){

var d = "msg="+msg.value;

sendReq('POST','./demo',d,startOrStop);

msg.value = "";

}

}

2.配置服务端

服务端的配置在

web.xml文件中,如下所示

keeper

keeper.servlet.Keeper

ScriptName

/keeperScript.js

1

keeper

/keeper

用在页面包含JavaScript时,这里的src一定要和上面配

置的一至。上面的设置除了为可选的设置外,其他的都是必要的,而且不能改

变。

3.编写事件处理代码,消息的处理代码如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println("Post..");

String msg = request.getParameter("msg");

Controller.action(new SendMsg(msg),"msg");

}

class SendMsg implements EventListener{

private String msg;

public SendMsg(String msg) {

this.msg = msg;

}

@Override

public void process(HttpServletRequest request, HttpServletResponse response) {

response.setCharacterEncoding("UTF-8");

PrintWriter out = null;

try {

out = response.getWriter();

if(msg!=null){

out.write(msg);

}

} catch (IOException e) {

e.printStackTrace();

}

finally{

if(out != null) {

out.close();

}

}

}

}

到这时,一个基本的keeper应用就完成了。其它部分请参考附件中的例子源码。

描述: comet的实现和应用例子

下载次数: 767

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值