WebSocket协议

websocket 简介

  (2013-04-09 15:39:28)
  分类: websocket

一 javascript

 

WebSocket是html5新增长的一种通讯协议,目前流行的浏览器都支持这个协议,例如Chrome,Safrie,Firefox,Opera,IE等等,对该协议支持最先的应该是chrome,从chrome12就已经开始支持,随着协议草案的不断变化,各个浏览器对协议的实现也在不停的更新。该协议仍是草案,没有成为标准,不过成为标准应该只是时间问题了,从WebSocket草案的提出到如今已经有十几个版本了,目前最新的是版本17,所对应的协议版本号为13,目前对该协议支持最完善的浏览器应该是chrome,毕竟WebSocket协议草案也是Google发布的。html

1.     WebSocket API简介html5

首先看一段简单的javascript代码,该代码调用了WebSockets的API。java

var ws = new WebSocket(“ws://echo.websocket.org”);node

ws.onopen = function(){ws.send(“Test!”); };git

ws.onmessage = function(evt){console.log(evt.data);ws.close();};github

ws.onclose = function(evt){console.log(“WebSocketClosed!”);};web

ws.onerror = function(evt){console.log(“WebSocketError!”);};chrome

这份代码总共只有5行,如今简单概述一下这5行代码的意义。编程

第一行代码是在申请一个WebSocket对象,参数是须要链接的服务器端的地址,同http协议使用http://开头同样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

第二行到第五行为WebSocket对象注册消息的处理函数,WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,当Browser和WebSocketServer链接成功后,会触发onopen消息;若是链接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;当Browser接收到WebSocketServer端发送的关闭链接请求时,就会触发onclose消息。咱们能够看出全部的操做都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,获得更好的用户体验。

 

为何引入WebSocket协议??

Browser已经支持http协议,为何还要开发一种新的WebSocket协议呢?咱们知道http协议是一种单向的网络协议,在创建链接后,它只容许Browser/UA(UserAgent)向WebServer发出请求资源后,WebServer才能返回相应的数据。而WebServer不能主动的推送数据给Browser/UA,当初这么设计http协议也是有缘由的,假设WebServer能主动的推送数据给Browser/UA,那Browser/UA就太容易受到攻击,一些广告商也会主动的把一些广告信息在不经意间强行的传输给客户端,这不能不说是一个灾难。那么单向的http协议给如今的网站或Web应用程序开发带来了哪些问题呢?

让咱们来看一个案例,如今假设咱们想开发一个基于Web的应用程序去获取当前Web服务器的实时数据,例如股票的实时行情,火车票的剩余票数等等,这就须要Browser/UA与WebServer端之间反复的进行http通讯,Browser不断的发送Get请求,去获取当前的实时数据。下面介绍几种常见的方式:

1.     Polling

这种方式就是经过Browser/UA定时的向Web服务器发送http的Get请求,服务器收到请求后,就把最新的数据发回给客户端(Browser/UA),Browser/UA获得数据后,就将其显示出来,而后再按期的重复这一过程。虽然这样能够知足需求,可是也仍然存在一些问题,例如在某段时间内Web服务器端没有更新的数据,可是Browser/UA仍然须要定时的发送Get请求过来询问,那么Web服务器就把之前的老数据再传送过来,Browser/UA把这些没有变化的数据再显示出来,这样显然既浪费了网络带宽,又浪费了CPU的利用率。若是说把Browser发送Get请求的周期调大一些,就能够缓解这一问题,可是若是在Web服务器端的数据更新很快时,这样又不能保证Web应用程序获取数据的实时性。

2.     Long Polling

上面介绍了Polling遇到的问题,如今介绍一下LongPolling,它是对Polling的一种改进。

Browser/UA发送Get请求到Web服务器,这时Web服务器能够作两件事情,第一,若是服务器端有新的数据须要传送,就当即把数据发回给Browser/UA,Browser/UA收到数据后,当即再发送Get请求给Web Server;第二,若是服务器端没有新的数据须要发送,这里与Polling方法不一样的是,服务器不是当即发送回应给Browser/UA,而是把这个请求保持住,等待有新的数据到来时,再来响应这个请求;固然了,若是服务器的数据长期没有更新,一段时间后,这个Get请求就会超时,Browser/UA收到超时消息后,再当即发送一个新的Get请求给服务器。而后依次循环这个过程。

这种方式虽然在某种程度上减少了网络带宽和CPU利用率等问题,可是仍然存在缺陷,例如假设服务器端的数据更新速率较快,服务器在传送一个数据包给Browser后必须等待Browser的下一个Get请求到来,才能传递第二个更新的数据包给Browser,那么这样的话,Browser显示实时数据最快的时间为2×RTT(往返时间),另外在网络拥塞的状况下,这个应该是不能让用户接受的。另外,因为http数据包的头部数据量每每很大(一般有400多个字节),可是真正被服务器须要的数据却不多(有时只有10个字节左右),这样的数据包在网络上周期性的传输,不免对网络带宽是一种浪费。

经过上面的分析可知,要是在Browser能有一种新的网络协议,能支持客户端和服务器端的双向通讯,并且协议的头部又不那么庞大就行了。WebSocket就是肩负这样一个使命登上舞台的。

 

三 websocket协议简介

 

WebSocket协议是一种双向通讯协议,它创建在TCP之上,同http同样经过TCP来传输数据,可是它和http最大的不一样有两点:1.WebSocket是一种双向通讯协议,在创建链接后,WebSocket服务器和Browser/UA都能主动的向对方发送或接收数据,就像Socket同样,不一样的是WebSocket是一种创建在Web基础上的一种简单模拟Socket的协议;2.WebSocket须要经过握手链接,相似于TCP它也须要客户端和服务器端进行握手链接,链接成功后才能相互通讯。

下面是一个简单的创建握手的时序图:

这里简单说明一下WebSocket握手的过程。

当Web应用程序调用new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer创建握手链接的过程。

1.     Browser与WebSocket服务器经过TCP三次握手创建链接,若是这个创建链接失败,那么后面的过程就不会执行,Web应用程序将收到错误消息通知。

2.     在TCP创建链接成功后,Browser/UA经过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。

例如:

GET /chat HTTP/1.1

Host: server.example.com

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==

Origin: http://example.com

Sec-WebSocket-Protocol: chat,superchat

Sec-WebSocket-Version: 13

3.     WebSocket服务器收到Browser/UA发送来的握手请求后,若是数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手链接,并给出相应的数据回复,一样回复的数据包也是采用http协议传输。

HTTP/1.1 101 Switching Protocols

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Sec-WebSocket-Protocol: chat

4.     Browser收到服务器回复的数据包后,若是数据包内容、格式都没有问题的话,就表示本次链接成功,触发onopen消息,此时Web开发者就能够在此时经过send接口想服务器发送数据。不然,握手链接失败,Web应用程序会收到onerror消息,而且能知道链接失败的缘由。

四 websocket与TCP,HTTP的关系。

 

WebSocket与http协议同样都是基于TCP的,因此他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是经过TCP的系统接口进行传输的。WebSocket和Http协议同样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是确定的,WebSocket在创建握手链接时,数据是经过http协议传输的,正如咱们上一节所看到的“GET/chat HTTP/1.1”,这里面用到的只是http协议一些简单的字段。可是在创建链接以后,真正的数据传输阶段是不须要http协议参与的。

具体关系能够参考下图:

 

 

五websocket server

 

果要搭建一个Web服务器,咱们会有不少选择,市场上也有不少成熟的产品供咱们应用,好比开源的Apache,安装后只需简单的配置(或者默认配置)就能够工做了。可是若是想搭建一个WebSocket服务器就没有那么轻松了,由于WebSocket是一种新的通讯协议,目前仍是草案,没有成为标准,市场上也没有成熟的WebSocket服务器或者Library实现WebSocket协议,咱们就必须本身动手写代码去解析和组装WebSocket的数据包。要这样完成一个WebSocket服务器,估计全部的人都想放弃,幸亏的是市场上有几款比较好的开源库供咱们使用,好比PyWebSocket,WebSocket-Node, LibWebSockets等等,这些库文件已经实现了WebSocket数据包的封装和解析,咱们能够调用这些接口,这在很大程度上减小了咱们的工做量。

下面就简单介绍一下这些开源的库文件。

1.     PyWebSocket

PyWebSocket采用Python语言编写,能够很好的跨平台,扩展起来也比较简单,目前WebKit采用它搭建WebSocket服务器来作LayoutTest。

咱们能够获取源码经过下面的命令

svn checkouthttp://pywebsocket.googlecode.com/svn/trunk/ pywebsocket-read-only

更多的详细信息能够从http://code.google.com/p/pywebsocket/获取。

2.     WebSocket-Node

WebSocket-Node采用JavaScript语言编写,这个库是创建在nodejs之上的,对于熟悉JavaScript的朋友可参考一下,另外Html5和Web应用程序受欢迎的程度愈来愈高,nodejs也正受到普遍的关注。

咱们能够从下面的链接中获取源码

https://github.com/Worlize/Websocket-Node

3.     LibWebSockets

LibWebSockets采用C/C++语言编写,可定制化的力度更大,从TCP监听开始到封包的完成咱们均可以参与编程。

咱们能够从下面的命令获取源代码

git clone git://git.warmcat.com/libwebsockets

相关文章
相关标签/搜索