公司的惯例是每周五都会有一个分享会,内容大概是前端,后台,软件思想,工具使用,设计等,大家坐在一起听一听,说一说,交流一下。
这次是我给大家讲webSocket传输协议。
最初对webSocket的印象是:它是一种实时的,用于网上实时聊天。例如QQ.
那么,webSocket是什么东西?真实时?那底层是不是还是轮训 轮询?和Http的长连接有什么不同?(这些问题对于我来说有点难度啊)
简书作者:TheAlchemist写了三篇刨根问底HTTP和WebSocket协议,上面的问题就是从他的文章上摘抄的。链接地址:http://www.jianshu.com/p/265397f812d4
那么赶紧去看文档,文档很重要很重要。这里根据他的文章找到两个链接,都是中文版,RFC6455:http://download.csdn.net/detail/relan365/7426065,RFC2616:http://download.csdn.net/detail/yintiliang/3043455。
关键字搜索WEBSOCKET出现如下信息:WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duple)。一开始的握手需要借助HTTP请求完成。
全双工(Full-Duplex Transmissions):是指交换机在发送数据的同时也能够接收数据,两者同步进行,
这好像我们平时打电话一样,说话的同时也能够听到对方的声音。目前的交换机都支持全双工
优点:延迟小,速度快。
轮询:轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。轮询会造成对网络和通信双方资源的浪费,并且非实时。那么从实时的角度,websocket底层就不是轮询。
websocket是基于http协议的,借用http握手,比http多了两个东西。
Upgrade: websocket
Connection: Upgrade
websocket协议:由握手和数据传输这两部分组成。
握手:
GET /chat HTTP/1.1 //1
Host: server.example.com //2
Upgrade: websocket //3
upgrade是HTTP1.1中用于定义转换协议的header域。
它表示,如果服务器支持的话,客户端希望使用现有的「网络层」已经建立好的这个「连接(此处是TCP连接)」,
切换到另外一个「应用层」(此处是WebSocket)协议。
Connection: Upgrade //4
HTTP1.1中规定Upgrade只能应用在「直接连接」中,所以带有Upgrade头的HTTP1.1消息必须含有Connection头,
因为Connection头的意义就是,任何接收到此消息的人(往往是代理服务器)都要在转发此消息之前处理掉Connection中指定的域(不转发Upgrade域)。
如果客户端和服务器之间是通过代理连接的,那么在发送这个握手消息之前首先要发送CONNECT消息来建立直接连接。
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== //5
Origin: http://example.com //6
作安全使用,防止跨站攻击,浏览器一般会使用这个来标识原始域
Sec-WebSocket-Protocol: chat, superchat //7
Sec-WebSocket-Version: 13 //8
第7行标识了客户端支持的子协议的列表(关于子协议会在下面介绍),
第8行标识了客户端支持的WS协议的版本列表,
第5行用来发送给服务器使用(服务器会使用此字段组装成另一个key值放在握手返回信息里发送客户端)。
数据传输:
数据传输使用的是一系列的数据帧,并且要进行掩码处理,
FIN:1bit,表示是消息的最后一帧,如果消息只有一帧,那第一帧就是最后一帧。
RSV1,RSV2,RSV3:每个1bit,且必须是0,除非扩展定义为非零。如果接收到的是非零,但扩展没有定义,那就要关闭连接。
Opcode:4bit,解释Payload数据,有不同的状态,如果状态未知,必须马上关闭连接。
0x0(附加数据帧),0x1(文本数据帧),0x2(二进制数据帧),
0x3-7(保留为以后的非控制帧使用),0xB-F(保留为以后的控制帧使用),
0x8(关闭连接帧),0x9(ping),0xA(pong).
Mask:1bit,掩码,定义是否需要掩码处理,如果是1表示进行了掩码处理。
Masking-key:域的数据就是掩码秘钥,用于解码payloadData,
Payload length:7位,7+16位,7+64位,payload数据的长度,如果是0-125,就是真实的payload 长度,如果是126,那么接着后面2个字节对应的16位无符号整数 就是payload的数据 长度,如果是127,那么后面2个字节对应的64位无符号整数就是payload的数据长度。
Masking-key:0到4个字节,如果mask设为1则有4个字节的掩码解密秘钥,否则无。
Payload-data:任意长度数据。包含有扩展定义数据和应用数据,如果没有定义扩展则没有此项,仅含有应用数据。