给websocket加入心跳包防止自动断开连接
生活随笔
收集整理的這篇文章主要介紹了
给websocket加入心跳包防止自动断开连接
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
var userId = $("#userId").val();
var lockReconnect = false; //避免ws重復連接
var ws = null; //判斷當前瀏覽器是否支持WebSocket
var wsUrl = serverConfig.cyberhouse_ws+userId;
createWebSocket(wsUrl); //連接wsfunction createWebSocket(url) {try {if ('WebSocket' in window) {ws = new WebSocket(url);} else if ('MozWebSocket' in window) {ws = new MozWebSocket(url);} else {layui.use(['layer'], function() {var layer = layui.layer;layer.alert("您的瀏覽器不支持websocket的協(xié)議,建議使用新版谷歌、火狐等瀏覽器,請勿使用IE10以下瀏覽器,360瀏覽器請使用極速模式,不要使用兼容模式!");});}initEventHandle();} catch(e) {reconnect(url);console.log(e);}
}function initEventHandle() {ws.onclose = function() {reconnect(wsUrl);console.log("llws連接關(guān)閉!"+new Data().toUTCString());};ws.onerror = function() {reconnect(wsUrl);console.log("llws連接錯誤!");};ws.onopen = function() {heartCheck.reset().start(); //心跳檢測重置console.log("llws連接成功!"+new Data().toUTCString());};ws.onmessage = function(event) {//如果獲得到消息、心跳檢測重置heartCheck.reset().start(); //拿到任何消息都說明當前連接是正常的console.log("llws收到消息啦:"+event.data);if (event.data != 'pong') {var obj = eval("("+event.data+")");layui.use(['layim'], function(layim) {if (obj.type == "onlineStatus") {layim.setFriendStatus(obj.id, obj.content);} else if (obj.type == "friend" || obj.type == "group") {layim.getMessage(obj);}});}};
}//監(jiān)聽窗口關(guān)閉事件,當窗口關(guān)閉時,主動去關(guān)閉websocket連接,防止連接還沒斷開就關(guān)閉窗口,server斷會拋異常
window.onbeforeunload = function() {ws.close();
}function reconnect(url) {if (lockReconnect) return;lockReconnect = true;setTimeout(function() { //沒連接上會一直重連,設(shè)置延遲避免請求過多createWebSocket(url);lockReconnect = false;}, 2000);
}//心跳檢測
var heartCheck = {timeout: 540000, //9分鐘發(fā)一次心跳timeoutObj: null,serverTimeoutObj: null,reset: function() {clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);return this;},start: function() {var self = this;this.timeoutObj = setTimeout(function() {//這里發(fā)送一個心跳,后端收到后,返回一個心跳消息,//onmessage拿到返回的心跳就說明連接正常ws.send("ping");console.log("ping!");self.serverTimeoutObj = setTimeout(function() {//如果超過一定時間還沒重置,說明后端主動斷開了ws.close(); //如果onclose會執(zhí)行reconnect,我們執(zhí)行ws.close()就行了,如果直接執(zhí)行reconnect會觸發(fā)onclose導致重連兩次}, self.timeout)}, this.timeout)}
}
//收到客戶端消息后調(diào)用的方法
@OnMessage
public void onMessage(String message, Session session) {if (message.equals("ping")) {} else {...}
}
系統(tǒng)發(fā)現(xiàn)websocket每隔10分鐘自動斷開連接,搜了很多博客都說設(shè)置一下nignx的
keepalive_timeout
proxy_send_timeout
proxy_connect_timeout
proxy_read_timeout
這四個字段的時長即可,然而好像并不生效。遂采取心跳包的方式每隔9分鐘客戶端自動發(fā)送ping消息給服務端,服務端不需要返回。即可解決問題。
轉(zhuǎn)自:https://blog.csdn.net/jkxqj/article/details/77848466
總結(jié)
以上是生活随笔為你收集整理的给websocket加入心跳包防止自动断开连接的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jsonschema中的$ref的循环引
- 下一篇: python: 判断字符串是否为合法的j