WebSocket让我们可以在客户端和web服务端之间实现实时通信,不需要客户端发起请求,服务端就可以直接向客户端发送数据,目前大多数浏览器都支持WebSocket协议。由于这一特性,它能够应用到很多场景下,比如游戏,服务实时监控,IM,直播等。
WebSocket是一种在一个TCP连接上进行全双工通信的协议,它与HTTP同样默认工作在80和443端口,并且支持HTTP代理和中间件,所以WebSocket能够适配HTTP协议。WebSocket的工作机制是通过HTTP协议建立连接,再使用WebSocket协议进行数据通信,过程如下:
- 客户端向web服务端发起http1.1请求,请求头中带有Connection: Upgrade和Upgrade: WebSocket,要求将协议转变为WebSocket协议。
- 服务端如果支持WebSocket协议,同样返回Connection: Upgrade头和Upgrade: WebSocke响应头。
- 双方一旦建立连接,即可进行双向的WebSocket数据传输,就不再是HTTP数据了。
可以使用telnet进行实验。
首先发送请求建立连接,这里需要将整个WebSocket的URL作为path。
$ telnet www.myserver.com 80
GET ws://www.myserver.com/myws HTTP/1.1
Host: www.myserver.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: 7KjJnV4J6RcHj6xFm5IDwQ==
成功的话很快收到响应。
HTTP/1.1 101 Switching Protocols
Server: nginx/1.14.2
Date: Fri, 11 Jan 2019 23:50:27 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: BCc8E9VXXx699+tqKe+wYd3DUvI=
服务端返回101 Switching Protocols,切换协议到WebSocket,双方即完成连接建立,后续就是WebSocket数据通信了。
客户端发送的Sec-WebSocket-key实际上是随机字节的base64编码,这里随便发个xxx也是可以的,而服务端响应的Sec-WebSocket-Accept是该编码的hash,这个机制只是用来防止缓存代理发送同样的会话,并没有任何加密鉴权校验等功能。
我们可以通过Chrome的调试界面看到WebSocket会话信息。
参考
https://en.wikipedia.org/wiki/WebSocket
https://en.wikipedia.org/wiki/HTTP/1.1_Upgrade_header
感谢您的阅读,有任何问题请交流指正。peace~