websocket协议握手的实现

分类:技术文档 - HTML5 | 阅读(4007) | 发布于:2015-10-27 13:31

最新版本的websocket协议没有了key1和key2这两个罗嗦的玩意,看来html5小组也在精简实现规则,这里不是全部的头部,比如应该有 cookie和User-Agent、Accept等,但都与实现无关,所以不贴出来了。
GET /pub/chat?q=me HTTP/1.1
Host: localhost:8080
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 7
Sec-WebSocket-Origin: null
Sec-WebSocket-Protocol: my-custom-chat-protocol
Sec-WebSocket-Key: /4VCUCTU2R4ycJl99yQWXw==
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
好,没有了Sec-WebSocket-Key1 和 Sec-WebSocket-Key2,只有一个Sec-WebSocket-Key,对于整天跟编码打交到的程序员,一眼就可以看出来:这个是一个经过base64编码后的数据,不过你不需要解码该数据,需要把这个字符串连接上一个固定的字符串:
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
至于为什么是上面这个一堆,我没有深入研究,实际上websocket的草案我也是大致的浏览,因为平常很忙,没有细心去钻研。 把Sec-WebSocket-Key:后的字符串,即:/4VCUCTU2R4ycJl99yQWXw== 连接上那一串固定字符串,生成一个这样:
/4VCUCTU2R4ycJl99yQWXw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
假设该字符串存储在变量 key 中:
对该字符串先用 sha1安全散列算法计算出二进制的值,然后用base64对其进行编码,即可以得到握手后的字符串:
// sha1函数第二个参数为 true,sha1返回的为二进制格式数据
$response_key = base64_encode(sha1($key, true));
最终的结果应该是:
i/yxBvO+uGlGAOVqFUhEdVQS8mM=
对照实现看看是否一样, 生成后,返回给客户端:
HTTP/1.1 101 Switching Protocols\r\n 
Upgrade: websocket\r\n 
Connection: Upgrade\r\n 
Sec-WebSocket-Accept: i/yxBvO+uGlGAOVqFUhEdVQS8mM=\r\n\r\n
好,用你的socket输出给浏览器,就可以完成握手了。

标签:websocket握手