WebSocket是一个在单TCP连接上进行全双工通信的协议。
允许服务器主动向客户端推送消息。

WebSocket本质上一种计算机网络应用层的协议,用来弥补http协议在持久通信能力上的不足。

  • HTTP 协议有一个缺陷:通信只能由客户端发起,不具备服务器推送能力。所以进行双向通信时必须使用webSocket。
  • 这种单向请求的特点,注定了如果服务器由连续的状态变化,客户端想要获知会非常麻烦。我们只能使用“轮询”:每隔一段时间,就像服务器发送要给请求。而轮询的效率非常的低。浪费资源。
  • 轮询的危害:服务端被迫维持来自每个客户端的大量不同的连接
    大量的轮询请求会造成高开销,比如会带上多余的header,造成了无用的数据传输。

websocket是先通过HTTP协议完成第一次握手

他们的握手过程

1
2
3
4
5
6
7
8
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

其中专属于websocket的由upgrade,connection,sec开头的内容。
最后返回响应,表示websocket连接建立完成

1
2
3
4
5
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

优缺点

优点:

WebSocket协议一旦建议后,互相沟通所消耗的请求头是很小的
服务器可以向客户端推送消息了
缺点:

少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)

心跳

心跳就是客户端定时的给服务端发送消息,证明客户端是在线的, 如果超过一定的时间没有发送则就是离线了。
已知:nginx 代理的 websocket 转发,无消息连接会出现超时断开问题
两种解决办法

  1. 修应nginx配置信息
  2. websocket发送心跳包
    主动触发有两种。
    主动断开连接
    ws.close();
    主动发送消息
    ws.send(“hello world”);

断线时如何解决

心跳包机制:

它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。
下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定掉线了。

总结:

WebSocket 是为了在 web 应用上进行双通道通信而产生的协议,相比于轮询HTTP请求的方式,WebSocket 有节省服务器资源,效率高等优点。
WebSocket 中的掩码是为了防止早期版本中存在中间缓存污染攻击等问题而设置的,客户端向服务端发送数据需要掩码,服务端向客户端发送数据不需要掩码。
WebSocket 中 Sec-WebSocket-Key 的生成算法是拼接服务端和客户端生成的字符串,进行SHA1哈希算法,再用base64编码。
WebSocket 协议握手是依靠 HTTP 协议的,依靠于 HTTP 响应101进行协议升级转换。