Websocket实现断网重连
代码如下:
定义的变量如下:
var lockReconnect = false;//避免重复连接
var wsUrl = "ws://localhost:8080/websocket/111"; // websocket链接
var ws;// websocket对象
首先判断是否支持websocket
if ("WebSocket" in window) {
....
}else{
alert("您的浏览器不支持websocket 请更换浏览器后重试!");
}
创建一个websocket对象
function createWebSocket(){
try {
ws = new WebSocket(wsUrl);
websocketInit();//对websocket对象进行初始化
} catch (e) {
console.log('创建异常 执行重连。。');
websocketReconnect(wsUrl);//调用重连方法
}
}
createWebSocket(); // 创建websocket
创建了一个websocketInit方法 对websocket进行初始化
function websocketInit () {
// 建立 websocket 连接成功触发事件
ws.onopen = function (evt) {
onOpen(evt);//连接成功后执行的方法
};
// 断开 web socket 连接成功触发事件
ws.onclose = function (evt) {
websocketReconnect(wsUrl);
onClose(evt);//断开连接成功后执行的方法
};
// 接收服务端数据时触发事件
ws.onmessage = function (evt) {
onMessage(evt);// 接收服务端数据时执行的方法
};
// 通信发生错误时触发
ws.onerror = function (evt) {
websocketReconnect(wsUrl);
onError(evt);// 通信发生错误时执行的方法
};
};
执行的方法
连接以后 重置心跳检测
接收数据后
如果是正常的返回心跳数据
再执行心跳检测
每次执行心跳检测 向服务器发送一条数据 服务器就会返回一条数据(只要在设置的延时内) 客户端再接收到数据 就会重新调用心跳检测方法
不过拿到任何消息都说明当前连接是正常的
function onOpen(evt) {
console.log("建立连接");
//心跳检测重置
heartCheck.start();
}
function onClose(evt) {
console.log("连接已关闭...");
}
function onMessage(evt) {
console.log('接收消息: ' + evt.data);
var data = JSON.parse(evt.data);
console.log(data);
console.log(data.heart);
if (data.hasOwnProperty("heart")) {// 存在key为heart
if (data.heart=="live"){// 心跳正常 再次执行
heartCheck.start();
console.log('心跳正常 再次执行心跳检测方法!');
}
return;
}
}
function onError(evt) {
console.log('通信错误:' + evt.data);
}
执行断网重连的方法
设置延迟一直调用 createWebSocket方法连接
function websocketReconnect(url) {
if (lockReconnect) { // 是否已经执行重连
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
var tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 5000);
}
心跳检测的方法
每30s执行一次心跳检测
每次执行心跳检测 向服务器发送一条数据 服务器就会返回一条数据(只要在设置的延时(30秒)内) 客户端再接收到数据 就会重新调用心跳检测方法
如果发生异常 就会调用ws.close();方法 close方法就会一直重复的调用重连方法 直到再次连接上服务器 完成断网重连!
//心跳检测
var heartCheck = {
timeout: 30000,
timeoutObj: null,
serverTimeoutObj: null,
start: function () {
console.log('开始心跳检测');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function () {
//发送测试信息,后端收到后,返回一个消息,
ws.send("1");
self.serverTimeoutObj = setTimeout(function () {
ws.close();
}, self.timeout);
}, this.timeout)
}
}
完整的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var lockReconnect = false;//避免重复连接
var wsUrl = "ws://localhost:8080/websocket/111"; // websocket链接
var ws;
if ("WebSocket" in window) {
function createWebSocket(){
try {
ws = new WebSocket(wsUrl);
websocketInit();
} catch (e) {
console.log('catch');
websocketReconnect(wsUrl);
}
}
createWebSocket(); // 创建websocket
function websocketInit () {
// 建立 web socket 连接成功触发事件
ws.onopen = function (evt) {
onOpen(evt);
};
// 断开 web socket 连接成功触发事件
ws.onclose = function (evt) {
websocketReconnect(wsUrl);
onClose(evt);
};
// 接收服务端数据时触发事件
ws.onmessage = function (evt) {
onMessage(evt);
};
// 通信发生错误时触发
ws.onerror = function (evt) {
websocketReconnect(wsUrl);
onError(evt);
};
};
function onOpen(evt) {
console.log("建立连接");
//心跳检测重置
heartCheck.start();
}
function onClose(evt) {
console.log("连接已关闭...");
}
function onMessage(evt) {
console.log('接收消息: ' + evt.data);
var data = JSON.parse(evt.data);
console.log(data);
console.log(data.heart);
if (data.hasOwnProperty("heart")) {// 存在key为heart
if (data.heart=="live"){// 心跳正常 再次执行
heartCheck.start();
console.log('心跳正常 再次执行心跳检测方法!');
}
return;
}
}
function onError(evt) {
console.log('通信错误:' + evt.data);
}
function websocketReconnect(url) {
if (lockReconnect) { // 是否已经执行重连
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
var tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 5000);
}
//心跳检测
var heartCheck = {
timeout: 30000,
timeoutObj: null,
serverTimeoutObj: null,
start: function () {
console.log('执行心跳检测');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function () {
//发送测试信息,后端收到后,返回一个消息,
ws.send("heart");
self.serverTimeoutObj = setTimeout(function () {
ws.close();
}, self.timeout);
}, this.timeout)
}
}
}else{
alert("您的浏览器不支持websocket 请更换浏览器后重试!");
}
</script>
</body>
</html>
测试图
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0smaixGaykVeWd0Yx40MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1IDNyETM1UTMxATNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)