詳情參考websocket+心跳包:https://www.cnblogs.com/1wen/p/5808276.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
<script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
alert("您的瀏覽器支持 WebSocket!");
// 打開一個 web socket
var ws = new WebSocket("ws://localhost:9998/echo");
ws.onopen = function()
{
// Web Socket 已連接上捺弦,使用 send() 方法發(fā)送數(shù)據(jù)
ws.send("發(fā)送數(shù)據(jù)");
alert("數(shù)據(jù)發(fā)送中...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert("數(shù)據(jù)已接收...");
};
ws.onclose = function()
{
// 關(guān)閉 websocket
alert("連接已關(guān)閉...");
};
}
else
{
// 瀏覽器不支持 WebSocket
alert("您的瀏覽器不支持 WebSocket!");
}
}
</script>
</head>
<body>
<div id="sse">
<a href="javascript:WebSocketTest()">運行 WebSocket</a>
</div>
</body>
</html>
上面一段是菜鳥代碼,但是要清楚websocket是前后端交互的長連接狼纬,前后端也都可能因為一些情況導(dǎo)致連接失效并且相互之間沒有反饋提醒羹呵。因此為了保證連接的可持續(xù)性和穩(wěn)定性骂际,websocket心跳重連就應(yīng)運而生疗琉。
以下是我自己項目的代碼,不要在意內(nèi)容歉铝,在意形式就好盈简,里面摻雜著心跳包插件。
var ws;
var wsUrl="ws://"+window.location.host+"/mss/h5WebSocket";
var lockReconnect = false;//避免重復(fù)連接的開關(guān)
var tempTrainAlarm={};
function createWebSocket(url)
{
try{
ws=new WebSocket(url);
initEventHandle();
}
catch(e){
reconnect(url);
}
};
function initEventHandle()
{
ws.onclose=function(){
reconnect(wsUrl);
};
ws.onerror=function(){
reconnect(wsUrl);
};
ws.open=function(){
heartCheck.reset();
}
ws.onmessage=function(message){
if(message.data!=="HeartBeat")
{
var outerData=JSON.parse(message.data);
if(outerData.websocketType=="logout")//實際這一步不太需要太示,如果報文發(fā)不過來這一條也能保證執(zhí)行而已柠贤,下面已經(jīng)有了
{
window.location.href="/mss/h5/login.html";
}
var dataStr=outerData.msg.toString();//這一步是從message里的data的msg轉(zhuǎn)成字符串
var data=JSON.parse(dataStr);//將字符串轉(zhuǎn)換成對象
if(outerData.websocketType=="tab")
{
tabSession[0] = data;
// tab_interval_off = true;
}
else if(outerData.websocketType=="mqFtp")
{
mqFtpSession[0] = data;
}
else if(outerData.websocketType=="alarmList")
{
alarmListSession.push(data);
}
else if(outerData.websocketType=="logout")
{
window.location.href="/mss/h5/login.html";
}
else if(outerData.websocketType=="SwitchValueList")
{
SwitchValueListSession.push(data);
}
else if(outerData.websocketType=="VobcTrainOnLine")
{
VobcTrainOnLineSession[0] = data;
// vobc_interval_off = true;
}
else if(outerData.websocketType=="WEBSOCKET_AXLE_SECTION_RESET_TYPE")
{
axleSession.push(data);
}
else if(outerData.websocketType=="WEBSOCKET_LTE_ALARM_TYPE")
{
lteSession.push(data);
}
else if(outerData.websocketType=="WEBSOCKET_LTE_ALARM_TAB_TYPE")
{
lteTabSession[0] = data;
}
else console.log("多了一種websocketType");
}
heartCheck.reset();
}
};
function reconnect(url)
{
if(lockReconnect) return;
lockReconnect = true;
//沒連接上會一直重連,設(shè)置延遲避免請求過多
setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 2000);
}
var heartCheck = {
timeout: 60000,//60s
timeoutObj: null,
serverTimeoutObj: null,
reset: function(){
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
this.start();
},
start: function(){
var self = this;
this.timeoutObj = setTimeout(function(){
ws.send("HeartBeat");
self.serverTimeoutObj = setTimeout(function(){
ws.close();//如果onclose會執(zhí)行reconnect类缤,我們執(zhí)行ws.close()就行了.如果直接執(zhí)行reconnect 會觸發(fā)onclose導(dǎo)致重連兩次
}, self.timeout)
}, this.timeout)
},
};
createWebSocket(wsUrl);