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)