WebSocket是一种网络传输协议,可以在单个TCP连接上进行全双工通信,位于OSI模型的应用层。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,服务器可以主动向客户端发送消息。在WebSocket API中,浏览器和服务器只需要完成一个握手,就可以建立持久性的连接,并进行双向数据传输。
WebSocket之前的方式
在WebSocket之前,浏览器(客户端)和服务器之间进行实时通信有以下几种方式:
- 短轮询(short polling):
- 浏览器每隔一段时间(比如每秒)就向服务器发送HTTP网络请求,服务器再把最新的数据返回给浏览器
- 这种方式的缺点在于浏览器需要不断地向服务器发送网络请求,而每次HTTP请求头和响应头中携带的信息可能是一样的,真正有用的数据只有一小部分,这样会消耗很多带宽资源
- 长轮询(long polling):
- 同样是浏览器每隔一段时间就向服务器发送HTTP网络去获取最新数据,区别在于服务器在接收到网络请求之后不会立即将最新数据返回给客户端,而是在数据发生变化或者达到一定的响应时间限制之后才将请求结果返回给客户端,从而减少了客户端请求的次数
- 这种方式的缺点在于服务器在将客户端请求挂起的时候,同样存在资源消耗
这些方式都不是很好的方式,在这种情况下,HTML5定义了WebSocket协议,它能更好地节省服务器资源和带宽,并且能够更实时地进行通信
WebSocket的优点
- 较少的控制开销:在建立连接之后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小
- 更强的实时性:由于协议是全双工的,因此服务器可以随时主动地向客户端传递消息。相比于HTTP请求需要等待客户端发送请求之后服务器才能响应,延迟明显更少。相比于长轮询,WebSocket能够更频繁地传递数据
- 保持连接状态:由于WebSocket建立连接之后,除非一方主动断开,否则这个连接会一直保持,因此在之后的通信过程中,就可以省略部分状态信息。(相比于HTTP每次请求都是独立的)
- 更好的二进制支持:WebSocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容
- 可以支持协议拓展:用户可以自定义子协议
- 更好的压缩效果:相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率
WebSocket连接的建立过程
WebSocket 是独立的、建立在TCP上的协议。它建立连接的过程(handshake)如下:
- 首先建立TCP连接
- 在建立TCP连接之后,浏览器会先通过HTTP请求来告知服务器进行协议升级,具体的做法是在带上一些特殊的请求头:
其中Connection: Upgrade
用于告知服务器进行协议升级,Upgrade: websocket
用于告知想要升级的协议是Websocket,Set-Websocket-Key
是一段随机生成的base64码,用于服务器返回响应