握手协议的客户端数据已经由浏览器代劳了,服务器端需要我们自己来实现,目前市场上开源的实现也比较多如:
- Kaazing WebSocket Gateway(一个 Java 实现的 WebSocket Server);
- mod_pywebsocket(一个 Python 实现的 WebSocket Server);
- Netty(一个 Java 实现的网络框架其中包括了对 WebSocket 的支持);
- node.js(一个 Server 端的 JavaScript 框架提供了对 WebSocket 的支持);
- WebSocket4Net(一个.net的服务器端实现);
其实在目前的.net4.5框架中已经实现了WebSocket,不用官方实现,我们自己来写个简单的。服务器端需要根据协议来握手、接收和发送。
握手
首先我们再来回顾下握手协议:
关键是服务器端Sec-WebSocket-Accept,它是根据Sec-WebSocket-Key计算出来的:
- 客户端发到服务器的内容:
- 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
- 从服务器到客户端的内容:
- HTTP/1.1 101 Switching Protocols
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
- Sec-WebSocket-Protocol: chat
- 取出Sec-WebSocket-Key,与一个magic string “258EAFA5-E914-47DA-95CA-C5AB0DC85B11” 连接成一个新的key串;
- 将新的key串SHA1编码,生成一个由多组两位16进制数构成的加密串;
- 把加密串进行base64编码生成最终的key,这个key就是Sec-WebSocket-Key;
- /// <summary>
- /// 生成Sec-WebSocket-Accept
- /// </summary>
- /// <param name="handShakeText">客户端握手信息</param>
- /// <returns>Sec-WebSocket-Accept</returns>
- private static string GetSecKeyAccetp(byte[] handShakeBytes,int bytesLength)
- {
- string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);
- string key = string.Empty;
- Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n"