WebSocket 握手

浏览器发出的 WebSocket 握手请求类似于下面的样子:

  1. GET / HTTP/1.1
  2. Connection: Upgrade
  3. Upgrade: websocket
  4. Host: example.com
  5. Origin: null
  6. Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
  7. Sec-WebSocket-Version: 13

上面的头信息之中,有一个 HTTP 头是Upgrade。HTTP1.1 协议规定,Upgrade字段表示将通信协议从HTTP/1.1转向该字段指定的协议。Connection字段表示浏览器通知服务器,如果可以的话,就升级到 WebSocket 协议。Origin字段用于提供请求发出的域名,供服务器验证是否许可的范围内(服务器也可以不验证)。Sec-WebSocket-Key则是用于握手协议的密钥,是 Base64 编码的16字节随机字符串。

服务器的 WebSocket 回应如下。

  1. HTTP/1.1 101 Switching Protocols
  2. Connection: Upgrade
  3. Upgrade: websocket
  4. Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
  5. Sec-WebSocket-Origin: null
  6. Sec-WebSocket-Location: ws://example.com/

上面代码中,服务器同样用Connection字段通知浏览器,需要改变协议。Sec-WebSocket-Accept字段是服务器在浏览器提供的Sec-WebSocket-Key字符串后面,添加 RFC6456 标准规定的“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”字符串,然后再取 SHA-1 的哈希值。浏览器将对这个值进行验证,以证明确实是目标服务器回应了 WebSocket 请求。Sec-WebSocket-Location字段表示进行通信的 WebSocket 网址。

完成握手以后,WebSocket 协议就在 TCP 协议之上,开始传送数据。