HTTP协议的弊端:仅支持客户端发起请求,服务器回复响应, 不支持服务器主动向客户端发送消息。
如果客户端想要获取服务器发送的消息,需要通过频繁的JavaScript和AJAX请求实现轮询,效率较低
HTTP1.1之前一个request一个response后, HTTP连接就结束了,HTTP1.1后使用长连接, 一次HTTP连接可以发送和接收多个request和response, 但二者数量始终相等, 以上两种轮询方式都比较浪费资源。
WebSocket是HTML5新增的协议, 它允许客户端和服务器直接进行全双工通信, 任何一方都可以通过连接将数据推送到另一端
WebSocket 特点
WebSocket利用HTTP协议来建立连接
请求报文
GET ws://www.zhangshuo.fun/chat/2 HTTP/1.1 请求行
Host: www.zhangshuo.fun
Connection: Upgrade
Upgrade: websocket
Origin: http://localhost:8080
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: Zjy6wfxsecUZfUE9fx9yBQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Connection: Upgrade 表示要升级协议
Upgrade: websocket 表示协议要升级为websocket
Sec-WebSocket-Version: 13 表示协议版本
Sec-WebSocket-Key 随机生成, 用于标识这个链接
响应报文
HTTP/1.1 101
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: 2BObMdUfPogZU5MGvSfQQm1dmGk=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
响应码101表示HTTP协议即将被更改为WebSocket协议
到此一个WebSocket连接就建立成功
TCP协议本身就是全双工通信, 但建立在TCP之上的HTTP协议的请求-响应机制限制了全双工通信, 因此WebSocket连接建立后, 就不再使用HTTP协议的机制了, 而是直接发送数据通信.
WebSocket的每条消息有可能被切分为多个数据帧, WebSocket 根据FIN判断当前数据帧是否为最后一个, Fin = 1 表示已经收到完整消息, Fin = 0 表示接收方还需要继续监听接收其余的数据.
opcode在数据交换的场景下,表示的是数据的类型。0x01表示文本,0x02表示二进制。而0x00比较特殊,表示延续帧, 即消息还未接收完