咋处理 微信COMET1181

Web端即时通讯技术因受限于浏览器嘚设计限制一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(Server-sent Events)本文将简要介绍这4种技术嘚原理,并指出各自的异同点、优缺点等

年的发展。这种分布式、无状态、基于TCP的请求/响应式、在互联网盛行的今天得到广泛应用的协議相对于互联网的迅猛发展,它似乎进步地很慢互联网从兴起到现在,经历了门户网站盛行的web1.0时代而后随着ajax技术的出现,发展为web应鼡盛行的web2.0时代如今又朝着web3.0的方向迈进。反观http协议从版本1.0发展到1.1,除了默认长连接之外就是缓存处理、带宽优化和安全性等方面的不痛鈈痒的改进它一直保留着无状态、请求/响应模式,似乎从来没意识到这应该有所改变

传统的web应用要想与服务器交互,必须提交一个表單(form)服务器接收并处理传来的表单,然后返回全新的页面因为前后两个页面的数据大部分都是相同的,这个过程传输了很多冗余的數据、浪费了带宽于是Ajax技术便应运而生。

groups、gmail等交互式应用中广泛使用此种技术才使得Ajax迅速被大家所接受。

Ajax的出现使客户端与服务器端傳输数据少了很多也快了很多,也满足了以丰富用户体验为特点的web2.0时代 初期发展的需要但是慢慢地也暴露了他的弊端。比如无法满足即时通信等富交互式应用的实时更新数据的要求这种浏览器端的小技术毕竟还是基于http协议,http协议要求的请求/响应的模式也是无法改变的除非http协议本身有所改变。

以即时通信为代表的web应用程序对数据的Low Latency要求传统的基于轮询的方式已经无法满足,而且也会带来不好的用户體验于是一种基于http长连接的“服务器推”技术便被hack出来。这种技术被命名为这个术语由Dojo

其实,服务器推很早就存在了在经典的client/server模型Φ有广泛使用,只是浏览器太懒了并没有对这种技术提供很好的支持。但是Ajax的出现使这种技术在浏览器上实现成为可能 google的gmail和gtalk的整合首先使用了这种技术。随着一些关键问题的解决(比如 IE 的加载显示问题)很快这种技术得到了认可,目前已经有很多成熟的开源Comet框架

以丅是典型的Ajax和Comet数据传输方式的对比,区别简单明了典型的Ajax通信方式也是http协议的经典使用方式,要想取得数据必须首先发送请求。在Low Latency要求比较高的web应用中只能增加服务器请求的频率。Comet则不同客户端与服务器端保持一个长连接,只有客户端需要的数据更新时服务器才主动将数据推送给客户端。

有关Comet技术的详细介绍文章请参见:《》、《》、《》、《》

浏览器发出XMLHttpRequest 请求,服务器端接收到请求后会阻塞请求直到有数据或者超时才返回,浏览器JS在处理请求返回信息(超时或有效数据)后再次发出请求重新建立连接。在此期间服务器端鈳能已经有新的数据到达服务器会选择把数据保存,直到重新建立连接浏览器会把所有数据一次性取回。

Iframe是html标记这个标记的src属性会保持对指定服务器的长连接请求,服务器端则可以不停地返回数据相对于第一种方式,这种方式跟传统的服务器推则更接近

在第一种方式中,浏览器在收到数据后会直接调用JS回调函数但是这种方式该如何响应数据呢?可以通过在返回数据中嵌入JS脚本的方式如“<script type="text/javascript">js_func(“data from server ”)</script>”,服务器端将返回的数据作为回调函数的参数浏览器在收到数据后就会执行这段JS脚本。

但是这种方式有一个明显的不足之处:IE、Morzilla Firefox 下端嘚进度栏都会显示加载没有完成而且 IE 上方的图标会不停的转动,表示加载正在进行Google 的天才们使用一个称为“”的 ActiveX 解决了在 IE 中的加载显礻问题,并将这种方法应用到了 gmail+gtalk 产品中

如果说Ajax的出现是互联网发展的必然,那么Comet技术的出现则更多透露出一种无奈仅仅作为一种hack技术,因为没有更好的解决方案Comet解决的问题应该由谁来解决才是合理的呢?浏览器html标准,还是http标准主角应该是谁呢?本质上讲这涉及箌数据传输方式,http协议应首当其冲是时候改变一下这个懒惰的协议的请求/响应模式了。

W3C给出了答案在新一代html标准html5中提供了一种浏览器囷服务器间进行全双工通讯的网络技术Websocket。从Websocket草案得知Websocket是一个全新的、独立的协议,基于TCP协议与http协议兼容、却不会融入http协议,仅仅作为html5嘚一部分于是乎脚本又被赋予了另一种能力:发起websocket请求。这种方式我们应该很熟悉因为Ajax就是这么做的,所不同的是Ajax发起的是http请求而巳。 

有关WebSocket的详细介请参见即时通讯网有关WebSocket的系列文章:《》、《》、《》。

从浏览器支持角度来看WebSocket已经近在眼前,但仍有一段较长的蕗要走特别是在中国这个IE6、7、8依然盛行的国家,旧版本浏览器的消亡需要很长一段时间在完全实现浏览器全兼容前,Comet技术可能仍然是朂好的解决方案不过,当前也已存在一些比较成熟的封装方案来解决这种兼容性限制比如:开源的Socket.io,详见《》

SSE(Server-Sent Event,服务端推送事件)是一种允许服务端向客户端推送新数据的HTML5技术与由客户端每隔几秒从服务端轮询拉取新数据相比,这是一种更优的解决方案

与WebSocket相比,它也能从服务端向客户端推送数据那如何决定你是用SSE还是WebSocket呢?概括来说WebSocket能做的,SSE也能做反之亦然,但在完成某些任务方面它们各有千秋。

WebSocket是一种更为复杂的服务端实现技术但它是真正的双向传输技术,既能从服务端向客户端推送数据也能从客户端向服务端推送数据。

WebSocket和SSE的浏览器支持率差不多大多数主流桌面浏览器两者都支持。在Android 4.3以及更早的版本中系统默认浏览器两者都不支持,Firefox和Chrome则完全支持;Android 4.4中系统默认浏览器两者都支持;Safari从5.0开始支持SSE(iOS系统从4.0开始),但直到6.0才正确地支持WebSocket(6.0之前的Safari所实现的WebSocket协议存在安全问题所以一些主流浏览器已经禁用了基于这个协议的实现)。

与WebSocket相比SSE有一些显著的优势。个人认为它最大的优势就是便利:不需要添加任何新组件用任何你习惯的后端语言和框架就能继续使用。你不用为新建虚拟机、弄一个新的IP或新的端口号而劳神就像在现有网站中新增一个页媔那样简单。我喜欢把这称为既存基础设施优势

SSE的第二个优势是服务端的简洁。相对而言WebSocket则很复杂,不借助辅助类库基本搞不定(我試过令人痛苦)。

因为SSE能在现有的HTTP/HTTPS协议上运作所以它能直接运行于现有的代理服务器和认证技术。而对WebSocket而言代理服务器需要做一些開发(或其他工作)才能支持,在写这本书时很多服务器还没有(虽然这种状况会改善)。SSE还有一个优势:它是一种文本协议脚本调試非常容易。事实上在本书中,我们会在开发和测试时用curl甚至直接在命令行中运行后端脚本。

不过这就引出了WebSocket相较SSE的一个潜在优势:WebSocket是二进制协议,而SSE是文本协议(通常使用UTF-8编码)当然,我们可以通过SSE连接传输二进制数据:在SSE中只有两个具有特殊意义的字符,它們是CR和LF而对它们进行转码并不难。但用SSE传输二进制数据时数据会变大如果需要从服务端到客户端传输大量的二进制数据,最好还是用WebSocket

WebSocket相较SSE最大的优势在于它是双向交流的,这意味向服务端发送数据就像从服务端接收数据一样简单用SSE时,一般通过一个独立的Ajax请求从客戶端向服务端传送数据相对于WebSocket,这样使用Ajax会增加开销但也就多一点点而已。如此一来问题就变成了“什么时候需要关心这个差异?”如果需要以1次/秒或者更快的频率向服务端传输数据那应该用WebSocket。0.2次/秒到1次/秒的频率是一个灰色地带用WebSocket和用SSE差别不大;但如果你期望重負载,那就有必要确定基准点频率低于0.2次/秒左右时,两者差别不大

从服务端向客户端传输数据的性能如何?如果是文本数据而非二进淛数据(如前文所提到的)SSE和WebSocket没什么区别。它们都用TCP/IP套接字都是轻量级协议。延迟、带宽、服务器负载等都没有区别除非……呃?除非什么

当你在享用SSE的既存基础设施优势,并在客户端和服务端脚本之间设了一个网络服务器区别就显现出来了。一个SSE连接不仅使用┅个套接字还会占用一个Apache线程或进程,如果用PHP它会为这个连接专门创建一个PHP新实例。Apache和PHP会使用大量的内存这会限制服务器所能支持嘚并行连接数。所以要做到用SSE在数据传输性能上和WebSocket完全一样,需要写一个自己的后端服务器当然,那些在任何情况下都会用自己的服務器并使用Node.js的人会觉得这有什么稀奇的。

说一下WebSocket在旧版本浏览器上的兼容当前,大约超过2/3的浏览器支持这些新技术移动端浏览器的支持率会低一些。依惯例每当需要双向套接字时,就会用到Flash并且WebSocket的向后兼容通常是用Flash来做,这已经相当复杂了如果浏览器上没有Flash,凊况更糟概括来说,WebSocket难兼容SSE易兼容。有关SSE的专项介绍文章请参见:《》

- 更多即时通讯技术资料:

- 即时通讯开发交流群: [推荐]

Web端即时通讯新手入门贴:

关于Ajax短轮询:找这方面的资料没什么意义,除非忽悠客户否则请考虑其它3种方案即可。

有关Comet技术的详细介绍请参见:《》

有关WebSocket的详细介绍请参见:《》

有关SSE的详细介绍文章请参见:《》

更多WEB端即时通讯文章请见:

交流:欢迎加入即时通讯开发交流群  

Jack Jiang同时昰和的作者可前往下载交流。

欢迎转载转载请注明出处(也可前往  找到我)。 

值得注意的是send只能发送纯文本信息,所以在发送之前进行序列化是有必要的

下面是封装后的可以登录、点对点通信的webSocket聊天室。


Comet 是一种新的 Web 应用架构基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据而不需要客户端显式的发出请求。Comet 架构非常适合事件驱动的 Web 应鼡以及对交互性和实时性要求很强的应用,如股票交易行情分析、聊天室和 Web 版在线游戏等本文在介绍 Comet 架构的基础上,详细说明了如何利用 WebSphere Application

包提供支持两者都实现了 Bayeux 协议。

该聊天室实际运行起来的截图如下我使用了几个不同的浏览器,并用了不同的用户来模拟多用户嘚效果


为开发这样的应用提供了良好的支持,可以作为很好的出发点



本文章仅代表作者本人观点,与 IBM 公司无关


布朗运动模拟 Comet 应用源玳码
聊天室 Comet 应用源代码
  • “”(周婷,developerWorks2007 年 8 月):本文介绍、比较了常用的“服务器推”方案。 
    • 成富任职于 IBM 中国软件开发中心目前在 CETI Web 2.0 小组從事开发工作。他毕业于北京大学信息科学技术学院获得计算机软件与理论专业硕士学位。

我要回帖

 

随机推荐