Comet---“服务器推”技术实现

Comet是一种服务器推数据的技术,基于HTTP长链接,避免因链接过多而导致的资源开销。对于智能化监控系统,是一种合适的技术选择。因为监控系统需要实时的把更新的信息推送给客户端。

以下部分引用至IBM官网:

Comet 简介

浏览器作为 Web 应用的前台,自身的处理功能比较有限。浏览器的发展需要客户端升级软件,同时由于客户端浏览器软件的多样性,在某种意义上,也影响了浏览器新技术的推广。在 Web 应用中,浏览器的主要工作是发送请求、解析服务器返回的信息以不同的风格显示。AJAX 是浏览器技术发展的成果,通过在浏览器端发送异步请求,提高了单用户操作的响应性。但 Web 本质上是一个多用户的系统,对任何用户来说,可以认为服务器是另外一个用户。现有 AJAX 技术的发展并不能解决在一个多用户的 Web 应用中,将更新的信息实时传送给客户端,从而用户可能在“过时”的信息下进行操作。而 AJAX 的应用又使后台数据更新更加频繁成为可能。

1. 传统的 Web 应用模型与基于 AJAX 的模型之比较

服务器推是一种很早就存在的技术,以前在实现上主要是通过客户端的套接口,或是服务器端的远程调用。因为浏览器技术的发展比较缓慢,没有为服务器推的实现提供很好的支持,在纯浏览器的应用中很难有一个完善的方案去实现服务器推并用于商业程序。最近几年,因为 AJAX 技术的普及,以及把 IFrame 嵌在“htmlfile“ ActiveX 组件中可以解决 IE 的加载显示问题,一些受欢迎的应用如 meebogmail+gtalk 在实现中使用了这些新技术;同时服务器推在现实应用中确实存在很多需求。因为这些原因,基于纯浏览器的服务器推技术开始受到较多关注,Alex RussellDojo Toolkit 的项目 Lead)称这种基于 HTTP 长连接、无须在浏览器端安装插件的服务器推技术为“Comet”。目前已经出现了一些成熟的 Comet 应用以及各种开源框架;一些 Web 服务器如 Jetty 也在为支持大量并发的长连接进行了很多改进。关于 Comet 技术最新的发展状况请参考关于 Comet wiki

下面介绍comet的java实现:

设定已经安装了TOMCAT7.0以及Eclipse,

  • 下载comet4j-tomcat7.jar以及comet4j.js,放置于工程对应目录
  • 修改tomcat的server.xml配置,改为使用nio.

<Connector URIEncoding="UTF-8" connectionTimeout="20000"

port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>

  • 在应用工程的web.xml中配置监听以及comet连接地址

<listener>

<listener-class>org.comet4j.core.CometAppListener</listener-class>

</listener>

<listener>

<description>ComnetListener</description>

<listener-class>comet.ComnetListener</listener-class>

</listener>

<servlet>

<display-name>CometServlet</display-name>

<servlet-name>CometServlet</servlet-name>

<servlet-class>org.comet4j.core.CometServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>CometServlet</servlet-name>

<url-pattern>/conn</url-pattern>

</servlet-mapping>

4. 服务端代码编写,这里我们需要编写一个ServletContextListener,定义好数据渠道,并传递数据。

如下的案例中,系统设置一个线程,每三秒从内存结构中读取数据。

import java.util.ArrayList;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

import monitorlogic.MonitorUser;

import org.comet4j.core.CometContext;

import org.comet4j.core.CometEngine;

 

public class ComnetListener implements ServletContextListener {

      private static final String CHANNEL1 = "num";

public void contextInitialized(ServletContextEvent arg0) {

CometContext cc = CometContext.getInstance();

cc.registChannel(CHANNEL1);

Thread helloAppModule = new Thread(new HelloAppModule(), "Sender App Module");

helloAppModule.setDaemon(true);

helloAppModule.start();

}

class HelloAppModule implements Runnable {

public void run()

{

while (true)

{

try

{

Thread.sleep(3000);

}

catch (Exception ex)

{

ex.printStackTrace();

}

CometEngine engine = CometContext.getInstance().getEngine();

StringBuffer htmlResult = new StringBuffer();

       ArrayList<Integer> al = MonitorUser.getUserList();

           int sum = 0;

           for (int i=0;i<al.size();i++)

           {

                 sum = sum +al.get(i);

           }

           int span = al.size()+1;

                                 

           engine.sendToAll(CHANNEL1, sum);

}

}

}

public void contextDestroyed(ServletContextEvent arg0)

{

     

}

}

5. web页面编写,将数据展示

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Insert title here</title>

<script type="text/javascript" src="js/comet4j.js"></script>

<script type="text/javascript">

function init(){

var kbDom = document.getElementById('bb');

JS.Engine.on({

num : function(bb){//侦听一个channel

kbDom.innerHTML = bb;

}

      });

JS.Engine.start('conn');

JS.Engine.on(

'start',function(cId,channelList,engine){

alert('连接已建立,连接ID为:' + cId);

});

}

</script>

</head>

<body οnlοad="init()">

      <h2>今日总计:<FONT color=red id="bb"></FONT>个</h2>

</body>

</html>

 


如果您认可本文,就点击下图的二维码关注本订阅号。长按下图的二维码,然后点击“识别图中的二维码”。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值