WebSocket
是什么
WebSocket
是一种网络通信协议。那么就有一个问题了:已经有了HTTP
协议,为什么还需要WebSocket
?
因为HTTP
协议有一个缺陷:通信只能由客户端发起,做不到服务器主动向客户端推送信息。 HTTP
协议的这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。轮询的效率低,非常浪费资源。因此,大佬们一直在思考,有没有更好的方法。WebSocket
就是这样出现的。
WebSocket
特点
WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。 WebSocket
允许服务器端与客户端进行全双工的通信。
其他的一些特点:
(1)建立在TCP
协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信,完全可以取代 Ajax。
(6)协议标识符是ws
(如果加密,则为wss
,对应 HTTPS 协议),服务器网址就是 URL。
WebSocket
握手
WebSocket
也要有一个握手过程,然后才能正式收发数据。
客户端发送数据格式如下:
JSON
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
- Connection:必须设置Upgrade,表示客户端希望连接升级
- Upgrade:必须设置Websocket,表示希望升级到Websocket协议
- Sec-WebSocket-Key:客户端发送的一个 base64 编码的密文,用于简单的认证秘钥。要求服务端必须返回一个对应加密的"Sec-WebSocket-Accept应答,否则客户端会抛出错误,并关闭连接
- Sec-WebSocket-Version :表示支持的Websocket版本
服务端返回的数据格式:
JSON
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol: chat
- HTTP/1.1 101 Switching Protocols:表示服务端接受 WebSocket 协议的客户端连接
- Sec-WebSocket-Accep:验证客户端请求报文,同样也是为了防止误连接。具体做法是把请求头里"Sec-WebSocket-Key"的值,加上一个专用的 UUID,再计算摘要
总结
WebSocket
是一种基于TCP
的网络通信协议。 优点如下:
- 较少的控制开销:数据包头部协议较小,不同于http每次请求需要携带完整的头部
- 更强的实时性:相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少
- 保持创连接状态:创建通信后,可省略状态信息,不同于HTTP每次请求需要携带身份验证
- 更好的二进制支持:定义了二进制帧,更好处理二进制内容
- 支持扩展:用户可以扩展websocket协议、实现部分自定义的子协议
- 更好的压缩效果:Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率