1.前言
由于公司前段时间开发一个类似直播的项目,想要一端能够控制其他端的呼入呼出,开麦闭麦等操作,传统的http请求不能做到服务器主动向客户端发请求,想要实时获取控制信息只能通过http进行轮询请求,但是这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。所以此刻websocket就显得很nice了。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
2.WebSocket 的简介
Websocket是一种在单个TCP连接上进行全双工通讯的协议。而http协议是半双工通讯协议。全双工和半双工这期间的区别相当于手机和对讲机的区别,手机在讲话的同时也能听到对方说话,对讲机只能一个说完另一个才能说。
在Websocket协议中,客户端和服务端只需要做一个握手的动作,就能形成一条通道,两者之间可以进行数据互相传送。
3.WebSocket连接过程
客户端首先发起HTTP握手,告诉服务端进行WebSocket协议通讯,并告知WebSocket协议版本(此次请求必须是get请求)。服务端确认协议版本,升级为WebSocket协议。之后如果有数据需要推送,会主动推送给客户端。
连接开始时,客户端使用HTTP协议和服务端升级协议,升级完成后,后续数据交换遵循WebSocket协议。
Request Headers
Connection: Upgrade 告诉服务器想要升级协议
Upgrade: websocket 升级协议到websocket协议
Sec-WebSocket-Version websocket的版本。
Sec-WebSocket-Key 对应服务端响应头的Sec-WebSocket-Accept,这是一个base64的随机字符串。由于没有同源限制,websocket客户端可任意连接支持websocket的服务。这个就相当于一个钥匙一把锁,避免多余的,无意义的连接。
Response Headers
关键是这个字段
Sec-WebSocket-Accept: 用来告知服务器愿意发起一个websocket连接, 值根据客户端请求头的Sec-WebSocket-Key计算出来
4.WebSocket API
4.1.WebSocket的建立
const Socket = new WebSocket(url, [protocol] );
以上代码中的第一个参数 url, 指定连接的 URL(url是以ws://开头,或者wss://开头)。第二个参数 protocol 是可选的,指定了可接受的子协议。
4.2.WebSocket 事件
以下是 WebSocket 对象的相关事件。假定我们使用了以上代码创建了 Socket 对象:
Socket.onopen 连接建立是触发的事件
Socket.onmessage 客户端接收服务端数据时触发的事件
Socket.onerror 通信发生错误时触发的事件
Socket.onclose 连接关闭时触发的事件
4.3.WebSocket 方法
Socket.send()使用连接发送数据
Socket.close()关闭连接
5.WebSocket的心跳和重连
弱网、断网所导致重连都是被动的,而在一般的websocket连接中都是存在心跳机制的,客户端和服务端约定一个特定的心跳消息用于检测链路是否通信正常。
我们通过心跳机制,在客户端来检测链路的正常,在约定时间间隔内收不到心跳或者其他任何通信消息时,客户端进行主动重连。
所以下面优化的,我们需要加一个心跳检测的方法:
心跳检测对象,定义了
timeout: 心跳超时时间
timeoutObj: 定时器变量
reset:重置心跳
start: 开启心跳
当连接成功时,开启心跳;在收到消息时,重置心跳并开启下一轮检测,所以我们只需要在onopen和onmessage中加入心跳检测就行
在实际使用过程中,发现有些浏览器,reconnect重连会多次触发,所以需要给重连加一把锁,当一个重连正在执行时,无法再触发一次重连。
网友评论