websocket

http://fins.iteye.com/blog/775257
WebSocketHTML 5的一个突破是它为新一代的网页编程提供了很多方便的API,使编程人员很容易的就可以做到很多样化的网页应用程序,而WebSocket API 就是其中一个。

[编辑] 什么是 Websocket API?WebSocket protocol 是HTML5一种新的协议(protocol)。它是实现了浏览器与服务器全双工通信(full-duplex)。

现在,很多网站为了实现即时通讯(real-time),所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(time interval)(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request d的模式带来很明显的缺点 – 浏览器需要不断的向服务器发出请求(request),然而HTTP request 的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽。

而比较新的技术去做轮询的效果是Comet – 用了AJAX。但这种技术虽然可达到全双工通信,但依然需要发出请求(reuqest)。

在 WebSocket API,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在此WebSocket 协议中,为我们实现即使服务带来了两大好处:

1. Header

互相沟通的Header是很小的-大概只有 2 Bytes

2. Server Push

服务器可以主动传送数据给客户端

[编辑] 握手协议在实现websocket连线过程中,需要透过浏览器发出websocket连线请求,然后服务器发出回应,这个过程通常称为“握手” (handshaking)。

浏览器请求(request from browser)
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com
^n:ds[4U


服务器回应(server response)
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sample
8jKS’y:G*Co,Wxa-


[编辑] 原理在请求中的Sec-WebSocket-Key1, Sec-WebSocket-Key2 和最后的数字(^n:ds[4U)都是随机的,服务器方面会用这些数据来构造出一个16Byte的回应。

把第一个Key的数字除以第一个KEY的空白间的数量,而第二个KEY也是如此。然后把这两个数字和最后的数字连接起来成为1个字串,而这个字串连接起来成为1个字串,而这个字串是MD5的和。

[编辑] 浏览器实现websocket的协议,浏览器扮演着一个很重要的角色。互联网巨擎Google一直都是不断推动互联网的发展,不断推出为互联网带来新的冲击。它也是不断推动HTML5发展的主力。永远走在互联网最前线的Google在它的Google Chrome支持了websocket。(Chrome 5 之后的版本都支持websocket,但因为websocket还未最终版本,草案不断更新,所以不同的版本会支持不同的草案)

此外,苹果公司当然也不断推动HTML5的发展,Safari浏览器也支持websocket了。

起初,Mozilla基金会的Mozilla Firefox会在4版本支持websocket(Firefox 4 正式版预计会在2011年初面世)。Opera软件公司方面在Opera 10.7和11.0的预览版本中也支持了websocket。然而,基于安全因素的考虑[1],两家宣布将暂时移除该功能。


socket通信开发,最重要的就是协议了。通信软件(QQ、MSN)、杀毒软件(360、金山)、电信软件(短信、通话)等行业软件有自己的协议。有了协议,我们可以无视语言和平台,使得大家都可以为这个平台做开发,就像我们用了同一种语言,同一个电波一样。总的来说,在通信程序开发中,协议成为了分步式处理、跨平台、跨语言的重要作用,在websocket中也不例外。

   协议分很多种,OSI的七层协议,如果现在记得不清楚的也没关系。在开发中,我们几乎只需了解TCP协议就行了,这里由于篇幅原因,也不对整编websocket协议进行整篇翻译。只对其中的几点需注意的地方进行一个说明吧。

注1:This Internet-Draft will expire on November 7, 2010.
P2 本篇过期时间为到2010年11月7日。这个应该不准,这个要浏览器的支持了,像Filefox4.0才会完全支持html5,如果你使用Chrome,那么也跟你得到的版本有关。不是那么特别的。

注2:A simpler solution would be to use a single TCP connection for traffic in both directions

websocket是一种基于一个TCP连接的全双工的通讯方式,也就是说,服务端可以主动推数据到客户端,客户端也可以发送数据到服务端。

注3:1.2. Protocol overview

The handshake from the client looks as follows:[省去协议内容]

The handshake from the server looks as follows:[省去协议内容]

在webcoket中,是由客户端先发送请求头信息到服务端,服务端对请求进行检查,如果是合法的请求头,则会发送握手信息到客户端。同是为每个客户端建产一个socket用来通信。这个socket有输入流,也有输出流,是一个全双工的tcp通信端口。

其中客户端的请求头和服务端的握手信息都是每行一个的键值对信息,且字符编码为ASCII 编码。这个很重要,因为在传送数据的时候,是以utf8做编码的。

注4:1.3 Opening handshake

建产握手。这个是整个websocket协议中最重要的一个环节。因为握手是建立连接,或进行下一步通信的关键,也是关系到你是否能和其它遵寻html5 websocket协议的浏览器(如chrome,fiirfox4.0等)进行通信的关键。

下面主要讲一点比较不容易计算的的地方。

            Sec-WebSocket-Key1: 18x 6]8vM;54 *(5: {   U1]8 z [ 8

        Sec-WebSocket-Key2: 1_ tx7X d < nw 334J702) 7]o}` 0

   For each of these fields, the server has to take the digits from the

   value to obtain a number (in this case 1868545188 and 1733470270

   respectively), then divide that number by the number of spaces

   characters in the value (in this case 12 and 10) to obtain a 32-bit

   number (155712099 and 173347027). These two resulting numbers are

   then used in the server handshake, as described below.



这里的两个key值,分别代表两个数。把上面的两个字符数数组转化成字符串后,变成了1868545188和1733470270。然后,再查看这两个key中空格字符的个数。

第一个key一共有12个空格。所以1868545188/12=155712099.同理,第二个key一共有10个空格1733470270/10=173347027



注5:P6 Data is sent in the form of UTF-8 text. Each frame of data starts with a 0x00 byte and ends with a 0xFF byte, with the UTF-8 text in between….

当握手成功后,就是进行数据传送了。注意 ,这个时候tcp连接已在经建立了,现在客户发送上来的时候就是纯纯的数据了。服务端要判断什么时候是一次数据请求的开始,什么时候是请求的结束。这个也要是处理在tcp发送中的黏包的问题。由于在tcp协议中,会存在两个缓冲区去存放发送的数据或接收的数据,如果没有显的分割符则会让服务端无法正确的识别两条命令。

       在websocket中,由于浏览端和服务端已经打好招呼,我发送的内容为utf-8 编码,如果我发送0x00,表是是一条命令的开始,如果发磅了0xFF,就表示这条命令已经结束了。这样就可以在浏览器的配合下很好解决上面黏包的问题。

       也可由下图所示:

Handshake

           |

           V

        Frame type byte <--------------------------------------.

           |      |                                            |

           |      `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+

           |                                                   |

           `--> (0x80 to 0xFE) --> Length --> Data... ------->-'



注6: P8 The |Origin| field is used to protect against unauthorized cross-

   origin use of a WebSocket server by scripts using the |WebSocket| API

   in a Web browser. The server specifies which origin it is willing to

   receive requests from by including a |Sec-WebSocket-Origin| field

   with that origin. If multiple origins are authorized, the server

   echoes the value in the |Origin| field of the client's handshake.

请求中的Origin字段,可以用来做身份验证的作用,如果使用得当,可以减少非法来源的连接建产。可以结合SEC-websocket-Origin来使用。其次,在请求中,还会伴随传过来头信息的md5码,可以起到防篡改的作用,可以进一步增强安全性验证。其实,还有一招,就算连接已经建立,我们还可以通过让客户端请求用户名和密码的方式使用业务逻辑再经过一次验证。

注7:P10 1.4 Cloing handshake

每个端只要向另一端口发送一个0xFF的信息,就表示连接已结束了。这个相关于tcp/ip协议中的fin/ack.

注8: 1.5 Design philosophy

这节是非正式的,但是作者有提到,websocket是可以和http共用监听端口的,以后也可能会扩展协议,由于现在传送的是字符串,后期可能会追求更好的压缩率,采用二进制传送。

其实,我们用现的协议开发时,也可以在发送的时候把数据压缩,在接收的时候把数据解压缩。

注9:3.1 Parsing websoket URLS

If the /secure/ flag is false, then append the string "ws://" to

       /url/. Otherwise, append the string "wss://" to /url/.

处理websocket链接。服务端只会去识别ws://或wss://开头的请求,这样的话,就不会和其它的监听服务进行冲突出了吧。

注:客户端发送的请求中,服务端地址为wss://www.example.com:8787/im?id=123456

那么www.example.com是服务端的地址,监听的端口号为8787,im是对应的请求名称,其中传送的参数为id,值为123456.

注10 :4 Client-side requirements

这章主要是以客户端(浏览器)为中心。所以一切的主语都是客户端。详细讲了客户端发送请求头和数据信息的内容。

注11  :5 Server-Side requirements

这章主要是以服务端(监听服务)为中心,详细服务端如何处理请求和处理握手的过程。

你可能感兴趣的:(应用服务器,浏览器,html5,互联网,chrome)