本文主要说一下WebSocket的含义、工作原理和特点,用一个例子展示如何使用它,以及对它心跳检测和重连。
1. WebSocket 是个啥?
WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议(独立的、创建在 TCP 上的)。
2. 功能是什么?
使客户端和服务器之间数据交换变得更加简单,允许服务端主动向客户端推送数据。
3. 如何交互?
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
4. 为何会出现这个websocket协议?
网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询使浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,这样会浪费很多的带宽等资源。
5. 特点:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
6. 一颗栗子展示它当如何使用:
//订阅地址获取, 建立连接
ajax({
url: path,
method: method,
}).then((res)=>{
this.loadWebsocket(res.url);
}).catch(() => {
console.error('websocket连接失败');
});
loadWebsocket=(url)=>{
//(1)建立webSoctket通道
if (window && 'WebSocket' in window) {
this.webSocket = new WebSocket(`ws://${url}`); // ws 统一资源标志符,类似于 HTTPS
}
//(2) 打开连接
this.webSocket.onopen = () => {
console.info('实时报警推送连接成功');
/**
* 心跳连接
*/
if (this.state.heartBeatTimeOut === false) {
if (this.heart) {
clearInterval(this.heart);
this.heart = null;
}
return;
}
// 防止定时器重复定义,先清除再定义
if(this.heart){
clearInterval(this.heart);
this.heart= null;
}
this.heart = setInterval(function () {
try {
this.webSocket.send('heartbeat');
} catch (error) {
if(this.heart){
clearInterval(this.heart);
this.heart = null;
}
}
}, 30000);
};
// (3)收到消息
this.webSocket.onmessage = (event) => { //客户端接收服务端数据
<div> 信息:{name},性别{sex},年龄{age}</div> // 消息:小明,性别未知,年龄18
};
// 连接发生错误时
this.webSocket.onerror = () => { //通信发生错误
console.error('连接中断');
//重新连接
this.reconnect();
};
//关闭
this.webSocket.onclose = (e) => {
console.error('连接中断');
//重新连接
this.reconnect();
//code为xx时,主动断开连接,不再重连
if (e.code === xx) return;
}
reconnect=()=> {
if(this.state.loopReconnect){
return;
}
this.setState({
loopReconnect: true
});
// 没连接上会一直重连,设置延迟避免请求过多
if (this.reconnectTimeOut){
clearTimeout(this.reconnectTimeOut);
this.reconnectTimeOut = null;
}
this.reconnectTimeOut = setTimeout(function(){
this.loadWebsocket();
this.setState({
loopReconnect: false //避免websocket重复连接
});
}, 4000);
}
注:通道了都建立好了,互通信息就好了啊,为什么要加个心跳???
在使用websocket的过程中,有时候会遇到网络断开的情况,但在网络断开的时候服务器端并没有触发onclose的事件。
这样就导致:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失。
因此需要一种机制来检测客户端和服务端是否处于正常的链接状态。因此就有了websocket的心跳了。
即:每隔一段时间会向服务器发送一个数据包,告诉服务器自己还活着,同时客户端会确认服务器端是否还活着,如果还活着的话,就会回传一个数据包给客户端来确定服务器端也还活着,否则的话,有可能是网络断开连接了。需要重连~
现在先用一个定时器模拟推送一条信息,结果应是 消息:小明,性别未知,年龄18
let i = 0;
setInterval(() => {
this._setAlarmInfo([{
id: 123,
name: '小明',
age: '18',
sex: '未知'
}]);
i++;
}, 10 * 1000);
参考资料: https://www.ruanyifeng.com/blog/2017/05/websocket.html https://www.runoob.com/html/html5-websocket.html