一 websoket心跳机制
- websoket心跳机制,是为了检测浏览器与服务端连接是否正常而存在的机制,如果不存在心跳机制,当浏览器异常或断网状态,浏览器或服务端可能一直发送无用的消息,浪费资源.检测原理就是定时向服务端发送消息表明连接正常,如果接收到响应就表明连接依旧存在可正常使用.
二 代码逻辑
//运行环境判断(获取不同环境名称的方法 dev/test/pre/online 本地等)
let environment = judgementEnvironment();
//各环境soket地址
let socketUrls = {
dev: 'ws://xxx.dev.xxxxxx.xxx:8282',
test: 'ws://xxx.test.xxxxxx.xxx:8282',
pre: 'wss://xxx.pre.xxxxxx.xxx:8282',
online: 'wss://xxx.xxxxxx.xxx:8282',
develoop: 'ws://xxx.dev.xxxxxx.xxx:8282'
};
//当前环境soket地址(根据当前环境的名称获取soket不同的地址)
let socketUrl = socketUrls[environment];
//保存事件对象
let soketMethods;
//保存websocket对象
let socket;
// reConnect函数节流标识符
let flag = true;
//心跳机制
let heart = {
timeOut: 20000,
timeObj: null,
serverTimeObj: null,
start: function () {
let self = this;
//清除延时器
this.timeObj && clearTimeout(this.timeObj);
this.serverTimeObj && clearTimeout(this.serverTimeObj);
this.timeObj = setTimeout(function () {
socket.send('ping');//发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数
//定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接
self.serverTimeObj = setTimeout(function () {
socket.close();
reConnect(socketUrl);
}, self.timeOut)
}, this.timeOut)
}
}
//建立websocket连接函数(传入各个事件绑定的方法 {socketOpen:fn,socketMessage:fn,socketError:fn,socketClose:fn,send_msg:'后端要接收的消息'})
function createWebsocket(methods) {
if (!soketMethods) soketMethods = methods;
try {
socket = new WebSocket(socketUrl);
socketInit(soketMethods);
} catch (e) {
//进行重连;
reConnect();
}
}
//对WebSocket各种事件进行监听(传入各个事件绑定的方法 {socketOpen:fn,socketMessage:fn,socketError:fn,socketClose:fn,send_msg:'后端要接收的消息'})
function socketInit(soketMethods) {
socket.onopen = function () {
//连接已经打开,重置心跳机制
heart.start();
socket.send(soketMethods.send_msg);
soketMethods.hasOwnProperty('socketOpen') && soketMethods.socketOpen();
}
socket.onmessage = function (event) {
//通过event.data获取server发送的信息
//对数据进行操作
soketMethods.hasOwnProperty('socketMessage') && soketMethods.socketMessage(event.data);
//收到消息表示连接正常,所以重置心跳机制
heart.start();
}
socket.onerror = function () {
//报错+重连
soketMethods.hasOwnProperty('socketError') && soketMethods.socketError('socket连接出错');
reConnect();
}
socket.onclose = function (event) {
reConnect();
soketMethods.hasOwnProperty('socketClose') && soketMethods.socketClose('socket连接关闭');
}
}
//重连函数
//因为重连函数会被socket事件频繁触发,所以通过函数节流限制重连请求发送
function reConnect() {
if (!flag) {
return;
}
flag = false;
setTimeout(function () {
createWebsocket();
flag = true;
}, 6000)
}
三 http/https与websocket的ws/wss的关系
- 在http下使用的是new WebSocket('ws://xxx');但是在切换到HTTPS后这个链接部分浏览器报错,实际上按照标准来是有如下对应关系.
http -> new WebSocket('ws://xxx')
https -> new WebSocket('wss://xxx')
- 也就是在https下应该使用wss协议做安全链接,且wss下不支持ip地址的写法,写成域名形式.