`

Comet,下一代Ajax?

    博客分类:
  • Ajax
阅读更多
   最近在看comet(server push)技术,经过一番google之后,大致理清了头绪,目前已经研究完一个开源的comet实现:pushlet([url]http://www.pushlets.com),包括前台的js,html代码以及后台的java代码,也基本搞清楚了关于pushlet的处理机制并且胡乱写了一部分pushlet的学习笔记,目前还在整理中,到时候将与大家分享!
    接下来的打算看另外两个开源的comet实现:dwr 2.0的reverse ajax和dojo的io.bind(),
如果有志同道合者大家可以一起来研究共同提高!

概念
     关于comet的最初定义来自这篇blog文章:http://alex.dojotoolkit.org/?p=545
     简单的说就是客户端发送一个请求,服务器接收它,并使用一个无限循环,将客户端需要的数据push到response中,并进行刷新,但是该response并不关闭,继续接收新的数据并刷新,直到客户端断开连接,该循环才结束退出。
     我们可以认为ajax解决了单用户响应的问题,而comet则解决了在保证性能的前提下进行协同多用户的响应问题。
     comet的优点在于它可以在任何时候向客户端发送数据,而不仅仅只是响应用户的输入请求。而发送数据是在一个已有的单连接上进行的。因此可以大大降低发送数据的延迟时间(建立connection的开销,以及客户端发送请求的等待时间)。

关于Event Web Server
     comet技术的一个重要组成部分就是event-drived web server,目前商用的实现已经出现,如lightstreamer(http://www.lightstreamer.com),这个我没有仔细看,只是跑了一下他给出的demo,还行!开源的实现就是apache+jetty(还要加一个mod)这个我还没有具体用过!

     有国人声称实现了comet server(http://cnc.agile.com/read.php?tid=319),还没去仔细研究,不知道如何。

      pushlet目前使用的是client pull做法,当然它的server push也将在不久的将来实现,它没有声称只能在专用的event-drived web server上运行,目前在tomcat运行环境下是可以的,不知道最多能承受多少用户同时访问还有待考证!

comet新体验
      我看了一下comet技术的一些实现,其中meebo(http://wwwm.meebo.com/)算是做的比较好的一个(gmail有谁用过?说说感受),我觉得它的web版本msn messager,比微软自己的web msn就要好用的多。
分享到:
评论
16 楼 hexiaodong 2006-10-23  
唉,再说详细点,希望这次你能看懂。普通web服务器不能保持长连接,因为如果你想保持长连接,只有一个办法:那就要在servlet的service()方法内执行类似下面的代码:
	while(true){
		if(hasMsg()){
			sendMsgToBrowser();
		}
	}

service()方法里是有死循环的,这样的话,接受了一个长连接请求之后,这个线程就不能去处理其他的请求了。

但在我的CometServer中不是这样的,request中有run(),这个方法内不必有死循环来发送消息。而是线程池中的多个线程循环访问request对列中的request对象,并调用run()方法,run()执行完后立即从对列中取下一个request并执行run()。在request的run方法内,会根据url去执行一个action的execute方法。因此,你可以写一个不包含while(true){}的action来处理当前的request对象。这样,CometServer何须为每个request分配一个固定的线程?CometServer只是在执行run()的片刻为它分配了线程,但不象普通web 容器那样线程执行完的同时也把request销毁了。CometServer会把request重新插入对列,并在不久的将来再次执行它run()方法,以便把新的需要写入浏览器的消息发送出去。
15 楼 mineral 2006-10-23  
hexiaodong 写道


原因就在于普通web容器中线程与http连接之间一对一的关系:每个线程占用大量的cpu资源和内存资源,所以web容器中允许的http处理线程数是非常有限的,一般设置不会超过200。而我的CometServer里面使用线程池里面固定数量的线程来处理大量连接的:它们不断轮流去执行 Request 的 run()方法。



楼主可能不认同我的观点,我觉得你的线程池和你所讲的普通web容器的线程池没有本质的区别。理由如下:

你用jdk5的特性创建一个线程池,分配线程去执行Request的run,也就是说,其实还是用一个线程去执行了你的方法。假设初始化线程数为200,当你的池里的200个线程都在干活的时候,这个时候,第201个request,来了,你的socket.accept()可以接受到新的Request,但是池里仍然没有线程来供你干活了,会不会就停止响应了呢? 还是一个socket,一个线程来响应,这点和http web容器的线程池工作道理,本质是一样的。如果刚好run里的方法写得比较重的话,一样的是cpu和内存的杀手。

另外,http协议本身是无状态的,只是容器实现加上了httpSession的具体不同实现,而CometServer(不单指楼主的CometServer)要实时地保持着客户端连接的socket,保存request的状态信息,用户标识信息等,在性能上和实现难度上,是不是比http 的server实现,难度还要更高一点。欢迎大家热烈讨论

14 楼 hexiaodong 2006-10-23  

1.没有做过大规模测试,能支持多少说不上来。但和servlet的实现还是有挺大差别的:由一个线程池(线程池的大小自己设置)来处理所有的这些连接,而不是每个线程处理一个连接。web容器中,不能在servlet里面向下面这样写代码:
	while(true){
		if(hasMsg()){
			sendMsgToBrowser();
		}
	}

的原因就在于普通web容器中线程与http连接之间一对一的关系:每个线程占用大量的cpu资源和内存资源,所以web容器中允许的http处理线程数是非常有限的,一般设置不会超过200。而我的CometServer里面使用线程池里面固定数量的线程来处理大量连接的:它们不断轮流去执行 Request 的 run()方法。


2、CometAction不是一个Servlet,不能获得session。但事实上action很可能期望能取到session,所以我自己借助HttpSessionListener来管理了session,以便能够 CometAction 用request(非servletRequest)获得session。request的state是必要的:为了加快accept的速度,在accept的时候,没有解析request的信息,而是在run的时候去解析的,因此request至少有两个状态:分别代表解析前和解析后的。但在开发CometAction的时候可以不必关心request的状态,只要确保Action的execute()能执行你期望的逻辑就可以了。记住,action的execute是会被线程池中不确定的某些线程以不确定的间隔不断被执行的,当然间隔不会很大,具体大小视服务器总共接受了多少的连接以及线程池中有多少线程而定。
13 楼 ppeter 2006-10-19  
我没有看过comet是什么东西,按照各位的讨论看来,这种技术可以运用到基于web的聊天程序实现.
最近几个月一直在做基于web的聊天程序,主要是运用了xmpp协议,关于这个协议的详细信息,大家不妨可以google一下.运用这个协议,有很多开源的组件包,比如smack.聊天的客户端和服务器端都有开源项目,我用过webchat,wildfire,等.推荐大家有需要的话可以去看看.
12 楼 poiuyt373 2006-10-19  
Comet就是保持长连接,一个请求就一直保持,除非自己实现web,否则很难实用
11 楼 jerry.li 2006-10-17  
pushlet 性能并不是很好,不知道dwr2.0的push做的怎么样。如果性能得不到提升,那末comet技术还是不用的好。
10 楼 macrochen 2006-10-17  
pi1ot 写道
我比较害怕和喜欢用感叹号的人交流,好像有个人在我面前冲着我大喊一样。

考,怎么开始喜欢使用感叹号了,一直没发觉这一点
9 楼 pi1ot 2006-10-17  
我比较害怕和喜欢用感叹号的人交流,好像有个人在我面前冲着我大喊一样。
8 楼 macrochen 2006-10-17  
pi1ot 写道

楼主说的comet其实就是:
while(1) { printf("<html>xxx</html>"); fflush(stdout); }
CGI直接输出HTML或者JS到浏览器。


简单的说,就是这样,所以comet不存在什么新技术,没有什么神秘可言!瓶颈主要集中在web server这一块,一般成熟的comet商业应用都会有一套它自己专用的web server,比如lightstreamer就是这样!
7 楼 macrochen 2006-10-17  
hexiaodong 写道
我实现的Comet Server,如果用电信宽待访问地址是http://agile.com/read.php?tid=319。我凭兴趣随便做的,做好了不知道该在什么项目里用,就这么闲摆着。

如果想试一试的话,下载后,放到tomcat的webapps目录下就行,然后访问index.jsp或者login.jsp。你可以看到一个很简单的聊天室的效果。

因为时间不多,所以用了很讨巧的方式来实现的。没有修改tomcat的源代码,而是在contextLoader的时候,另外开了一个socket端口用来接受comet连接。


现在还没时间去看comet server,希望在了解了其他几个comet实现之后能跟你交流交流!
6 楼 macrochen 2006-10-17  
Lucas Lee 写道
我认为基于http的聊天类应用,自始自终都只有两类做法(如果有其他类别,请指正我),
1.client pull。用JS等定时去服务器取数据。
  好处是保持了http server的无状态高并发,坏处是大量的pull动作其实是白费的。
2.server push。服务端的JSP等程序的响应永不关闭,定时输出新内容。
  好处是有新内容才输出,比较节省带宽等资源,坏处是长期占用了连接,丧失了无状态高并发的特点。
连接时有状态长期保持还是相反,这个也是传统意义上C/S与B/S的一大区别。所以看上去C/S会比B/S的并发负载能力低。但C/S的响应会更灵活和快速。

所以,server push不会是一个没有副作用的解决方案,是否适合还要仔细权衡。

补充一点,还能用Applet、flash、COM做基于UDP的应用,但那跟QQ差不多了,不在HTTP协议应用的范围内。


总结的非常有道理,server push通过维持长连接来得到快速将数据push到所有已连接的客户端,正因为如此所以不能采用传统的http web server,必须使用专用的event-drived web server来解决keep-alived connection的问题。
所以comet也没有什么新技术,一个成熟的comet应用除了需要一定的客户端脚本和服务器端代码的支持还需要特定的web server的支持!而一个成熟的comet framework则需要对这些客户端脚本和服务器代码进行良好的封装并能与各种event-drived web server能进行很好的结合,目前还没有比较成熟的event-drived web server出现,因此comet应用也没有象ajax那样普及。
与ajax应用相比,comet技术主要适用于即时通讯,实时数据监控,多用户协同交互的系统,所以comet应该算是ajax的一个有力补充和延伸!
5 楼 LucasLee 2006-10-17  
我认为基于http的聊天类应用,自始自终都只有两类做法(如果有其他类别,请指正我),
1.client pull。用JS等定时去服务器取数据。
  好处是保持了http server的无状态高并发,坏处是大量的pull动作其实是白费的。
2.server push。服务端的JSP等程序的响应永不关闭,定时输出新内容。
  好处是有新内容才输出,比较节省带宽等资源,坏处是长期占用了连接,丧失了无状态高并发的特点。
连接时有状态长期保持还是相反,这个也是传统意义上C/S与B/S的一大区别。所以看上去C/S会比B/S的并发负载能力低。但C/S的响应会更灵活和快速。

所以,server push不会是一个没有副作用的解决方案,是否适合还要仔细权衡。

补充一点,还能用Applet、flash、COM做基于UDP的应用,但那跟QQ差不多了,不在HTTP协议应用的范围内。
4 楼 pi1ot 2006-10-17  
robbin 写道
pi1ot 写道
几年前的几乎所有国内的CGI聊天室都是这么搞得,活生生把无状态高并发的HTTP给挤兑成了个占用Server端一个进程的长连接,服务器支持的并发数直线下降。
现在已经没这么玩得啦。

那现在一般怎么做的,都是定期刷新吗?

现在一般用flash通过socket与server通信,再用flash结合js输出,不再经CGI进程转手了。
楼主说的comet其实就是:
while(1) { printf("<html>xxx</html>"); fflush(stdout); }
CGI直接输出HTML或者JS到浏览器。

3 楼 robbin 2006-10-17  
pi1ot 写道
几年前的几乎所有国内的CGI聊天室都是这么搞得,活生生把无状态高并发的HTTP给挤兑成了个占用Server端一个进程的长连接,服务器支持的并发数直线下降。
现在已经没这么玩得啦。


那现在一般怎么做的,都是定期刷新吗?
2 楼 pi1ot 2006-10-17  
几年前的几乎所有国内的CGI聊天室都是这么搞得,活生生把无状态高并发的HTTP给挤兑成了个占用Server端一个进程的长连接,服务器支持的并发数直线下降。
现在已经没这么玩得啦。
1 楼 hexiaodong 2006-10-16  
我实现的Comet Server,如果用电信宽待访问地址是http://agile.com/read.php?tid=319。我凭兴趣随便做的,做好了不知道该在什么项目里用,就这么闲摆着。

如果想试一试的话,下载后,放到tomcat的webapps目录下就行,然后访问index.jsp或者login.jsp。你可以看到一个很简单的聊天室的效果。

因为时间不多,所以用了很讨巧的方式来实现的。没有修改tomcat的源代码,而是在contextLoader的时候,另外开了一个socket端口用来接受comet连接。

相关推荐

    comet的ajax实现

    comet两种实现之一的ajax实现,内部有源代码,这是一个聊天室的例子

    Comet,反向Ajax,直接就能跑

    dwr comet 反向ajax实力 直接抛 我打了一个包, 放到Tomcat,jetty下面就能直接跑了 很方便 还有注视 对新手 。。。。很好的

    comet-ajax

    comet-ajax聊天comet-ajax聊天comet-ajax聊天comet-ajax聊天comet-ajax聊天comet-ajax聊天comet-ajax聊天comet-ajax聊天comet-ajax聊天

    Comet, 下一代反向AJAX(即服务器推送技术- Server-side push)

    Comet 有时也称反向 Ajax 或服务器端推技术(server-side push)。其思想很简单:将数据直接从服务器推到浏览器,而不必等到浏览器请求数据。听起来简单,但是如果熟悉 Web 应用程序,尤其是 HTTP 协议,那么您就会...

    comet-ajax.rar

    Comet技术与Ajax技术在Web开发中的应用 Comet技术和Ajax技术都是Web应用程序中实现实时交互的重要手段,它们改变了传统的HTTP请求-响应模式,提升了Web应用的用户体验。在这篇文章中,我们将深入探讨这两种技术,...

    Ajax和Comet技术总结

    Comet是一种用于实现实时双向通信的技术,与传统的Ajax请求不同,Comet允许服务器向客户端推送数据,而不是仅由客户端发起请求。这在实时应用如聊天、股票报价或在线游戏等场景中特别有用。Comet有多种实现方式,...

    asp.net comet例子

    总结来说,这个ASP.NET Comet例子展示了如何利用Ajax和可能的IFrame技术在不同浏览器环境下实现实时的数据推送。开发者可以通过分析提供的Service.aspx和Service.aspx.cs文件,以及客户端的ajax.html,学习如何在ASP...

    comet4j 所需js以及comet4j-tomcat6.jar、comet4j-tomcat7.jar包

    在实际应用中,使用Comet4j可以显著提升用户体验,因为它避免了传统的AJAX轮询带来的频繁请求和高延迟问题。同时,Comet4j也支持大规模并发,可以处理成千上万的并发连接,这对于构建高并发、实时性的互联网应用非常...

    comet demo 向客户端推送例子

    Comet技术是一种基于HTTP长连接的反向Ajax技术,它允许服务器向客户端浏览器主动推送数据,从而实现双向通信。在Web应用中,通常的HTTP请求是客户端发起的,而Comet打破了这种模式,使得服务器可以在适当的时候主动...

    Comet Reverse Ajax

    EXAMPLE CODE FOR "Comet & Reverse Ajax" by Crane & McCarthy, FirstPress 2008 GENERAL SETUP The examples presented here use Groovy on Grails, a Java-based web technology stack. More details at ...

    web推送 comet技术

    客户端通常需要JavaScript来接收并处理服务器推送的数据,这可能涉及到AJAX或者WebSocket的使用,尽管Comet4J主要基于HTTP长连接,但也可以通过WebSocket进行优化,以提供更低延迟的双向通信。 为了在MyEclipse和...

    comet4j开发指南

    Comet4J是一个专为Java平台设计的服务器推送技术框架,它充分利用了AJAX(XMLHttpRequest)技术,实现了一种高效、实时的双向通信机制。在传统的HTTP协议中,服务器与客户端的交互是基于请求-响应模型的,即客户端...

    comet4j.jar

    - **性能优化**:探讨Comet4j在高并发环境下的性能表现,以及如何通过优化设置或代码来提高系统效率。 - **安全性考虑**:了解在使用Comet技术时可能面临的安全问题,如跨站脚本攻击(XSS)、跨站请求伪造(CSRF)...

    comet的demo

    - **反向Ajax**:Comet技术有时被称为反向Ajax,因为它是服务器向浏览器推送数据,而不是传统的Ajax(Asynchronous JavaScript and XML)由浏览器发起请求获取数据。 2. **Comet技术类型**: - **HTTP流**:...

    comet4j实例

    2. **通道(Channel)**:类似于传统的HTTP请求,但在Comet模式下,一个通道可以保持长时间的开放状态。服务器端和客户端可以通过通道进行双向通信。 3. **事件驱动**:Comet4j基于事件模型,当服务器端有新的数据...

    comet框架例子项目

    在本"Comet框架例子项目"中,我们可以深入理解并学习如何利用Comet技术构建实时通信的应用。 Comet的核心理念是通过长时间保持一个HTTP连接来实现服务器到客户端的数据推送,而不是每次有新数据时都创建新的连接。...

    comet套件(comet4j-tomcat6/7.jar、comet4j.js)

    1. `comet4j-tomcat6.jar` 和 `comet4j-tomcat7.jar`:这两个JAR文件是Comet4J为Tomcat 6和Tomcat 7优化的版本,它们提供了与Tomcat容器集成的能力,允许开发者在Tomcat环境下使用Comet4J实现服务器推送功能。...

Global site tag (gtag.js) - Google Analytics