======================================================
注:本文源代码点此下载
======================================================
让我们一起来了解html 5对当前web通信的改变。html 5 web socket通过在web上的一个单一socket定义了一个全双工通信信道为web通信带来了显著的改善。
html5 websocket:下一次web通信革命揭幕
【51cto译文】关于html 5的各种前沿技术应用51cto已经报道过很多,比如html 5的视频音频元素、html 5 web sql database、html5 file api以及如何从零开始构建一个html 5页面等等。这些都是html 5对当前web开发标准技术的升级或扩展。今天,51cto带您了解html 5的另一面——html 5 web socket,以及它对当前web通信的改变。
最近关于html 5 web socket的流言已经满天飞,它通过web上的一个单一socket定义了一个全双工通信信道,html 5 web socket并不是普通http通信的增强版,它代表着一个巨大的进步,特别是针对实时的、事件驱动的web应用程序 。
google的工程师ian hickson说“数据的字节数急剧减少到2字节,延迟从150毫秒减少到50毫秒,实际上,这两个因素已经足以引起google的兴趣了”。通过在一个浏览器中模拟全双工连接,html 5 web socket对web通信带来了显著的改善。
让我们与传统的解决方案相比,看看html 5 web socket是如何减少不必要的网络流量和延迟的。
当前的web通信——头疼的轮询 (polling)
通常,当浏览器访问一个网页时,会向托管该网页的web服务器发送一个http请求,web服务器识别这一请求,并返回响应。例如,股票价格,新闻报道,门票销售,流量模式,医疗设备读数等,在浏览器渲染页面时,响应可能会过期,如果你想获得最新的“实时”信息,你可以不断地手动刷新页面,但显然这不是最好的办法。
目前提供的实时web程序主要是围绕轮询和其它服务器端推送技术进行的,最著名的是comnet,它推迟了http响应的结束,基于comnet的推送通常是使用javascript结合长轮询(long polling)或流连接策略实现的。
使用轮询时,浏览器定期发送http请求,并立即收到响应,这种技术是交付实时信息的第一次尝试,显然,如果知道消息传递的时间间隔,这算是一个好办法,因为你可以在服务器上的信息可用时同步客户端请求,但实时数据往往是不可预测的,不可避免会产生一些不必要的请求,导致许多连接处于打开状态,有些不必关闭的连接却被关闭了。
使用长轮询时,浏览器向服务器发送一个请求,服务器在既定期限内保持请求处于打开状态,如果在此期间收到通知,向客户端发送一个包含消息的响应,如果在此期间没有收到消息,服务器发送一个响应终止打开的请求。最重要的是要理解,当你的信息容量很高时,长轮询与传统的轮询相比不提供任何性能改善。实际上,它可能更糟,因为长轮询可能会失控进入一个死循环。
使用流时,浏览器发送一个完整的请求,但服务器发送一个响应,并保存打开状态,然后不断更新使其一直保持打开(或在一段时间内保持打开),无论何时消息准备好发送时,响应就更新,但服务器不会发送一个结束的响应,因此连接就一直保持打开状态,后面发送的消息就可以继续使用这个连接。但流仍然是封装在 http中的,阻扰了防火墙和代理服务器选择缓冲区中的内容进行响应,因此消息传递的时间就延长了。许多流式comnet解决方案都转向了长轮询,另外,tls(ssl)连接可以用来屏蔽来自缓冲区的响应,但在这种情况下,每个连接消耗的服务器资源更多了。
最终,所有这些方法都提供了实时数据,包含http请求和响应头,其中包含许多额外的,不必要的头数据,最重要的是,全双工连接需要的不仅仅是从服务器到客户端的下行连接。为了模拟基于半双工http上的全双工通信,目前的许多解决方案都使用了两个连接:一个下行连接,一个上行连接。维护和协调这两个连接需要大量的系统开销,并增加了复杂性。简言之,http不是为实时的,全双工通信设计的,如图1所示,它显示了构建一个comnet web应用程序的复杂性,它从后端数据源使用发布/订阅模式基于半双工http显示实时数据。
图 1:comnet程序的复杂性
当你试图向外扩展那些comet解决方案时,情况变得更糟糕,模拟基于http的双向通信容易出错,即使最终用户感觉某些东西看起来象是一个实时web应用程序,但这种“实时”体验的代价都是非常高昂的,需要付出更多的延迟等待时间,不必要的网络流量和对cpu性能的拖累。
html 5 web socket ——拯救
html 5 web socket定义在html 5规范的通信章节,它代表web通信的下一个演变:通过一个单一的socket实现一个全双工,双向通信的信道。html 5 web socket提供了一个真正的标准,你可以使用它构建可扩展的实时web应用程序。此外,由于它提供了一个浏览器自带的套接字,消除了comet解决方案的许多问题,web socket显著降低了系统开销和复杂性。
为了建立一个web socket连接,客户端和服务器在初始握手期间要从http协议升级到websocket协议,如下面的例子:
例1:websocket握手(浏览器请求,服务器响应)
get /text http/1.1/r/n
upgrade: websocket/r/nconnection: upgrade/r/n
host: www.websocket.org/r/n.../r/n
http/1.1 101 websocket protocol handshake/r/nupgrade: websocket/r/n
connection: upgrade/r/n.../r/n
建立好连接后,websocket数据帧就可以在客户端和服务器之间以全双工模式传输,在同一时间任何方向,可以全双工发送文本和二进制帧,最小的帧只有2个字节。在文本帧中,每一帧始于0x00直接,止于0xff字节,数据使用utf-8编码。websocket文本帧使用终结器,而二进制帧使用一个长度前缀。
注意:虽然websocket协议已经可以支持多种客户端,但不能将原始数据传递给 javascript,因为javascript不支持字节类型,因此,如果客户端是javascript,二进制数据会被忽略,但可以传递给支持字节类型的客户端。
comet和html 5 web socket之间的对决
人们最关注的是html 5 web socket如何减少不必要的网络流量和延迟,我们比较一个轮询应用程序和web socket应用程序就知道了。
对于轮询的例子,我创建了一个简单的web应用程序,一个网页使用传统的发布/订阅模式从 rabbitmq消息代理请求实时的股票数据,它是通过轮询一个托管在web服务器上的java servlet实现的,rabbitmq消息代理从一个虚构的,不断更新价格的股票价格源接收数据,网页连接并订阅一个特定的股票频道(消息代理上的一个主题),使用xmlhttprequest每秒更新一次进行轮询。当收到更新时,执行一些计算,然后将股票数据显示在图2所示的表中。
图 2:一个javascript股票行情应用程序
注意:后端的股票源每秒实际上产生了大量的股票价格更新,因此使用每秒一次轮询的方式比使用长轮询方式更好,长轮询会产生许多连续的轮询,轮询会更有效地阻止传入更新。
这一切看起来还不错,但仔细观察,你就会发现这种应用程序存在严重的问题,例如,使用firefox的firebug插件(允许你调试网页和监控页面加载和脚本执行时间),你可以看到每秒都有一个get请求砸向服务器。打开live http headers(另一个firefox 插件,显示实时的http消息头流量)揭示每个请求关联的消息头开销数量是相当惊人的。下面两个例子显示了一个请求和响应的http消息头数据。
例2:http请求头
get /pollingstock//pollingstock http/1.1
host: localhost:8080user-agent: mozilla/5.0 (windows; u; windows nt 5.1; en-us; rv:1.9.1.5) gecko/20091102 firefox/3.5.5
accept: text/html,application/xhtml+xml,application/xml; q = 0 .9,*/*; q = 0 .8accept-language: en-us
accept-encoding: gzip,deflateaccept-charset: iso-8859-1,utf-8; q = 0 .7,*; q = 0 .7
keep-alive: 300connection: keep-alive
referer: http://www.example.com/pollingstock/cookie:showinheritedconstant = false ;
showinheritedprotectedconstant = false ;
showinheritedproperty = false ;
showinheritedprotectedproperty = false ;
showinheritedmethod = false ;
showinheritedprotectedmethod = false ;
showinheritedevent = false ;
showinheritedstyle = false ;
showinheritedeffect = false
例3:http响应头
http/1.x 200 ok
x-powered-by: servlet/2.5server: sun java system application server 9.1_02
content-type: text/html; charset = utf -8content-length: 21
date: sat, 07 nov 2009 00:32:46 gmt
http请求和响应头信息开销总共包括871字节,而且还不包括任何数据,当然,这只是一个例子,你的消息头数据完全可能低于871字节,但我也看到过消息头数据超过2000字节的情况。在这个例子中,股票主题消息数据大约只有20个字符。
当你把这样的程序大规模部署给用户时会怎么样?我们使用三个不同的用例观察一下该轮询应用程序关联的http请求和响应头数据需要的网络吞吐量。
用例a:1000客户端,每秒轮询一次
网络吞吐量(871x1000)=871000字节=6968000比特/秒(6.6mbps)
用例b:10000客户端,每秒轮询一次
网络吞吐量(871x10000)=8710000字节=69680000比特/秒(66mbps)
用例c:100000客户端,每秒轮询一次
网络吞吐量(871x100000)=87100000字节=696800000比特/秒(665mbps)
这是一个不必要的巨大的网络吞吐量,这时我们可以使用html 5 web socket,我使用html 5 web socket重构了应用程序,给网页添加了一个事件处理程序,同步监听来自消息代理的股票更新消息。每个消息都是一个web socket帧,开销只有2个字节(而不是871字节),再来看看对网络吞吐量的影响。
用例a:1000客户端,每秒轮询一次
网络吞吐量(2x1000)=2000字节=16000比特/秒(0.015mbps)
用例b:10000客户端,每秒轮询一次
网络吞吐量(2x10000)=20000字节=160000比特/秒(0.153mbps)
用例c:100000客户端,每秒轮询一次
网络吞吐量(2x100000)=200000字节=1600000比特/秒(1.526mbps)
正如你在图3中可以看到的,与轮询解决方案相比,html 5 web socket减少了不必要的网络流量。
图 3:比较轮询和websocket 应用程序之间的网络吞吐量
延迟减少怎么样呢?看看图4便知,图中上半部分显示了半双工轮询方案的延迟,这里我们假设消息从服务器传输到浏览器需要50毫秒,轮询方式引入许多额外的延迟,因为当响应完成时,一个新的请求已经发送到服务器了,这个新请求又需要50毫秒,在此期间服务器不能发送任何消息给浏览器,导致额外的服务器内存消耗。
图4下半部分显示了web socket方式产生的延迟,一旦连接升级到web socket,消息的传输会更及时,从服务器传输到浏览器仍然需要50毫秒,但web socket连接保持打开,之后就再也不用向服务器发送请求了。
图 4:轮询和web socket 应用程序之间的延迟对比
html5 web socket和kaazing websocket网关
目前,只有google的chrome浏览器原生支持html 5 web socket,但其它浏览器也将提供支持,若要解决这个限制,kaazing web socket网关为所有旧浏览器(ie 5.5+,firefox 1.5+,safari 3.0+和opera 9.5+)提供了一个完整的web socket仿真,因此你现在就可以使用html 5 web socket api。
web socket很了不起,但在你的浏览器中有一个全双工套接字连接后可以做什么呢?为了充分利用html 5 web socket的全部功能,kaazing为二进制通信提供了一个bytesocket库,为诸如stomp、amqp、xmpp、irc等协议提供了更高级的库,它们都是建立在web socket之上的。
例如,如果你为stomp或amqp协议使用了一个更高级的库,这时你可以直接与后端消息代理如rabbitmq进行通信,通过直接连接服务,不再需要额外的应用程序服务逻辑将这些双向,全双工tcp后端协议转换成非双向,半双工http连接,因为浏览器本身就可以理解这些协议。
图5:kaazing web socket网关扩展基于 tcp 的消息,并具有更好的性能
总结
html 5 web socket在实时web应用扩展性方面朝前迈出了一大步,正如你在本文中所看到的,html 5 web socket可以提供5000:1或 – 根据http消息头大小 – 1000:1的比例减少不必要的http头流量和3:1的比例减少通信延迟,这不是一个渐进式的改进,而是一次革命性的飞跃。
kaazing web socket网关让html 5 web socket代码能够在所有浏览器中运行,同时提供额外的协议库允许你充分利用html 5 web socket提供的全双工套接字连接功能,直接与后端服务进行通信。
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/