2. 概述
1996年IETF HTTP事情组发布了HTTP协议的1.0版本 ,到现在普遍利用的版本1.1,HTTP协议经历了17 年的发展。这种分布式、无状态、基于TCP的要求/相应式、在互联网盛行的本日得到广泛运用的协议,相对付互联网的迅猛发展,它彷佛进步地很慢。互联网从兴起到现在,经历了门户网站盛行的web1.0时期,而后随着ajax技能的涌现,发展为web运用盛行的web2.0时期,如今又朝着web3.0的方向迈进。反不雅观http协议,从版本1.0发展到1.1,除了默认长连接之外便是缓存处理、带宽优化和安全性等方面的不痛不痒的改进。它一贯保留着无状态、要求/相应模式,彷佛从来没意识到这该当有所改变。
好在HTML5的时期已经到来,为Web端即时通讯的实现带来了WebSocket和SSE(Server-sent Events)两种技能方案。
3. Ajax短轮询:脚本发送的http要求
传统的web运用要想与做事器交互,必须提交一个表单(form),做事器吸收并处理传来的表单,然后返回全新的页面,由于前后两个页面的数据大部分都是相同的,这个过程传输了很多冗余的数据、摧残浪费蹂躏了带宽。于是Ajax技能便应运而生。

Ajax是Asynchronous JavaScript and XML的简称,由Jesse James Garrett 首先提出。这种技能首创性地许可浏览器脚本(JS)发送http要求。Outlook Web Access小组于98年利用,并很快成为IE4.0的一部分,但是这个技能一贯很小众,直到2005年初,google在他的goole groups、gmail等交互式运用中广泛利用此种技能,才使得Ajax迅速被大家所接管。
Ajax的涌现使客户端与做事器端传输数据少了很多,也快了很多,也知足了以丰富用户体验为特点的web2.0时期 初期发展的须要,但是逐步地也暴露了他的弊端。比如无法知足即时通信等富交互式运用的实时更新数据的哀求。这种浏览器真个小技能毕竟还是基于http协议,http协议哀求的要求/相应的模式也是无法改变的,除非http协议本身有所改变。
4. Comet:一种hack技能
以即时通信为代表的web运用程序对数据的Low Latency哀求,传统的基于轮询的办法已经无法知足,而且也会带来不好的用户体验。于是一种基于http长连接的“做事器推”技能便被hack出来。这种技能被命名为Comet,这个术语由Dojo Toolkit 的项目主管Alex Russell在博文Comet: Low Latency Data for the Browser首次提出,并沿用下来。
实在,做事器推很早就存在了,在经典的client/server模型中有广泛利用,只是浏览器太
以下是范例的Ajax和Comet数据传输办法的比拟,差异大略明了。范例的Ajax通信办法也是http协议的经典利用办法,要想取得数据,必须首先发送要求。在Low Latency哀求比较高的web运用中,只能增加做事器要求的频率。Comet则不同,客户端与做事器端保持一个长连接,只有客户端须要的数据更新时,做事器才主动将数据推送给客户端。
Comet的实现紧张有两种办法,基于Ajax的长轮询(long-polling)办法和基于 Iframe 及 htmlfile 的流(http streaming)办法。
4.1 基于Ajax的长轮询(long-polling)办法
浏览器发出XMLHttpRequest 要求,做事器端吸收到要求后,会壅塞要求直到有数据或者超时才返回,浏览器JS在处理要求返复书息(超时或有效数据)后再次发出要求,重新建立连接。在此期间做事器端可能已经有新的数据到达,做事器会选择把数据保存,直到重新建立连接,浏览器会把所有数据一次性取回。
4.2 基于 Iframe 及 htmlfile 的流(http streaming)办法
Iframe是html标记,这个标记的src属性会保持对指定做事器的长连接要求,做事器端则可以一直地返回数据,相对付第一种办法,这种办法跟传统的做事器推则更靠近。
在第一种办法中,浏览器在收到数据后会直接调用JS回调函数,但是这种办法该如何相应数据呢?可以通过在返回数据中嵌入JS脚本的办法,如“<script type=\"大众text/javascript\公众>js_func(“data from server ”)</script>”,做事器端将返回的数据作为回调函数的参数,浏览器在收到数据后就会实行这段JS脚本。
但是这种办法有一个明显的不敷之处:IE、Morzilla Firefox 下真个进度栏都会显示加载没有完成,而且 IE 上方的图标会一直的迁徙改变,表示加载正在进行。Google 的天才们利用一个称为“htmlfile”的 ActiveX 办理了在 IE 中的加载显示问题,并将这种方法运用到了 gmail+gtalk 产品中。
5. Websocket:未来的办理方案1
如果说Ajax的涌现是互联网发展的一定,那么Comet技能的涌现则更多透露出一种无奈,仅仅作为一种hack技能,由于没有更好的办理方案。Comet办理的问题该当由谁来办理才是合理的呢?浏览器,html标准,还是http标准?主角该当是谁呢?实质上讲,这涉及到数据传输办法,http协议应首当其冲,是时候改变一下这个
W3C给出了答案,在新一代html标准html5中供应了一种浏览器和做事器间进行全双工通讯的网络技能Websocket。从Websocket草案得知,Websocket是一个全新的、独立的协议,基于TCP协议,与http协议兼容、却不会融入http协议,仅仅作为html5的一部分。于是乎脚本又被授予了另一种能力:发起websocket要求。这种办法我们该当很熟习,由于Ajax便是这么做的,所不同的是,Ajax发起的是http要求而已。
与http协议不同的要求/相应模式不同,Websocket在建立连接之前有一个Handshake(Opening Handshake)过程,在关闭连接前也有一个Handshake(Closing Handshake)过程,建立连接之后,双方即可双向通信。
从浏览器支持角度来看,WebSocket已经近在面前,但仍有一段较长的路要走,特殊是在中国这个IE6、7、8依然盛行的国家,旧版本浏览器的消亡须要很长一段韶光,在完备实现浏览器全兼容前,Comet技能可能仍旧是最好的办理方案。不过,当前也已存在一些比较成熟的封装方案来办理这种兼容性限定,比如:开源的Socket.io,详见《Socket.IO先容:支持WebSocket、用于WEB真个即时通讯的框架》。
6. SSE:未来的办理方案2
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的专项先容文章请拜会:《SSE技能详解:一种全新的HTML5做事器推送事宜技能》。
学习互换
系列资料Web端即时通讯新手入门贴:
关于Ajax短轮询:
找这方面的资料没什么意义,除非忽悠客户,否则请考虑其它3种方案即可。
有关Comet技能的详细先容请拜会:
有关WebSocket的详细先容请拜会:
有关SSE的详细先容文章请拜会:
更多WEB端即时通讯文章请见:
互换:欢迎加入即时通讯开拓互换群 215891622