WebSocket

WebSocket是一种在单个TCP连接上进行全双工通信的协议,本质上是基于TCP的应用层协议。WebSocket解决了HTTP协议的一个缺陷:通信只能由客户端发起,不具备服务器推送能力。WebSocket允许服务端主动向客户端推送数据,双向平等对话。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,属于服务器推送技术的一种。WebSocket的特点有:1.建立在TCP协议之上,服务器端的实现比较容易。2.与HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用HTTP协议,能通过各种HTTP代理服务器,握手时不容易被屏蔽。3.数据格式轻量,性能开销小,通信高效。4.可以发送文本和二进制格式数据。5.没有同源限制,客户端可以与任意服务器通信。6.协议标识符是ws(如果加密,则为wss),服务器网址就是URL。

 

WebSocket在2011年成为国际标准。在HTML5标准中增加了有关WebSocket协议的相关API,所以只要实现了HTML5标准的客户端,就可以与支持WebSocket协议的服务器进行全双工的持久通信。在WebSocket出现以前,创建一个和服务端进行双通道通信的web应用需要依赖HTTP协议进行不停地“轮询”。导致服务端被迫维持来自每个客户端的大量不同的连接,大量的轮询请求会造成高开销,比如会带上多余的header,造成无用的数据传输。

 

WebSocket的应用场景:即时聊天通信、多玩家游戏、在线协同编辑、实时数据流的拉取与推送、体育/游戏实况、实时地图位置、即时web应用程序、游戏应用程序、聊天应用程序。

虽然HTTP/2也具备服务器推送功能,但HTTP/2只能推送静态资源,无法推送指定的信息。

 

WebSocket是通过HTTP进行握手建立连接的,依靠 HTTP 响应101进行协议升级转换。TCP连接建立好之后,不再需要HTTP协议。

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

Upgrade: websocket;Connection: Upgrade;用来告诉服务器,发起的请求要用WebSocket协议。Sec-WebSocket-Key是客户端生成的一组16位的base64编码的随机数(拼接服务端和客户端生成的字符串,进行SHA1哈希算法,再用base64编码),用于标识这次连接。Sec-WebSocket-Version表示客户端WebSocket的协议版本号。Sec_WebSocket-Protocol表示使用的协议列表。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

响应头里的Sec-WebSocket-Accept值是将Sec-WebSocket-Key字段的值经过固定算法加密得到的,供客户端进行校验。Sec-WebSocket-Protocol表示确定使用的协议。

 

关于webSocket的断线重连问题。当连接断开时,只有客户端主动访问服务端才能实现重连。客户端会定时给服务端发送心跳包,客户端通过setInterval定时任务每隔3秒钟调用一次reconnect函数,reconnect会通过socket.readyState来判断这个websocket连接是否正常。如果不正常就会触发定时连接,每4s重试一次,直到连接成功。如果在指定的时间内没有收到服务器端返回心跳响应消息,因此说明连接断开。客户端需要通过onclose 关闭连接,服务端再次上线时需要清除双方的数据,若不清除会造成所有请求都会被视为离线。

解决断线问题的两个方案:1.修改Nginx配置信息。2.WebSocket发送心跳包。

posted @ 2023-04-11 07:14  Tiddler_7  阅读(26)  评论(0编辑  收藏  举报