Chrome早就采用了websocket草案10的协议,很多以前支持websocket的代码突然之间都用不了了,很多作者也没空更新,索性自己看了下草案,自己实现了一套。
握手协议还是非常简单的,Chrome发过来的header大概是这样的:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 8
要答复的头大概是这样的:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
实际上这里要处理的就是算出这个Sec-WebSocket-Accept的值。这个非常简单,首先拿到Sec-WebSocket-Key,也就是dGhlIHNhbXBsZSBub25jZQ==,把它和字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼在一起:
var key = request.headers['sec-websocket-key'] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
然后对这个key做一个SHA-1的加密,对加密后的字符串再base64就可以了,用nodejs写出来就是这样的:
var sha1 = Crypto.createHash('sha1');
key = sha1.update(key).digest('base64');
这个里面的key值就是最终要返回给客户端的值了,这样就算完成握手了。