系統發現websocket每隔1分鍾自動斷開連接,搜了很多博客都說設置一下nginx的proxy_read_timeout
但是這個時間過長會影響服務器性能,采取心跳包的方式每隔1分鍾客戶端自動發送ping消息給服務端,服務端需要返回pong。即可解決問題。
心跳機制發送的信息在后台判斷不發送至客戶端即可。
var webSocket = null;
function send_msg() {
var t = "";
if (webSocket != null) {
var input_msg = document.getElementById("input_msg").value.trim();
if (input_msg == "") {
return;
}
webSocket.send(input_msg);
// 清除input框里的信息
document.getElementById("input_msg").value = "";
// var msg_board = document.getElementsByClassName("msg_board")[0];
// var received_msg = input_msg;
// var old_msg = msg_board.innerHTML;
// msg_board.innerHTML = old_msg + received_msg + "<br>";
// // 讓滾動塊往下移動
// msg_board.scrollTop = msg_board.scrollTop + 40;
} else {
alert("您已掉線,請重新進入聊天室...");
}
};
function closeWs() {
webSocket.close();
};
function initWebSocket() {
var roomName = document.getElementById("input_roomName").value;
var userName = document.getElementById("userName").value;
// 房間名不能為空
if (roomName == null || roomName == "") {
alert("請輸入房間名");
return;
}
var userJson = roomName+","+userName;
if ("WebSocket" in window) {
if (webSocket == null) {
var url = "ws://127.0.0.1:8080/websocket/" + userJson;
// 打開一個 web socket
webSocket = new WebSocket(url);
} else {
alert("您已進入聊天室...");
}
webSocket.onopen = function () {
heartCheck.reset().start(); //心跳檢測重置
alert("已進入聊天室,暢聊吧...");
};
webSocket.onmessage = function (evt) {
heartCheck.reset().start(); //拿到任何消息都說明當前連接是正常的
var msg_board = document.getElementsByClassName("msg_board")[0];
var received_msg = evt.data;
var old_msg = msg_board.innerHTML;
msg_board.innerHTML = old_msg + received_msg + "<br>";
// 讓滾動塊往下移動
msg_board.scrollTop = msg_board.scrollTop + 40;
};
webSocket.onclose = function () {
// 關閉 websocket,清空信息板
alert("連接已關閉...");
webSocket = null;
document.getElementsByClassName("msg_board")[0].innerHTML = "";
};
}
else {
// 瀏覽器不支持 WebSocket
alert("您的瀏覽器不支持 WebSocket!");
}
}
//websocket維持連接檢測
var heartCheck = {
timeout: 60000, //1分鍾發一次
timeoutObj: null,
serverTimeoutObj: null,
reset: function(){
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function(){
var self = this;
this.timeoutObj = setTimeout(function(){
//這里發送一個心跳,后端收到后,返回一個心跳消息,
//onmessage拿到返回的心跳就說明連接正常
webSocket.send("發送維持連接消息");
console.log("發送維持連接消息!")
self.serverTimeoutObj = setTimeout(function(){//如果超過一定時間還沒重置,說明后端主動斷開了
webSocket.close(); //如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
}, self.timeout)
}, this.timeout)
}
}
后台代碼修改
// 收到客戶端消息后調用的方法 @OnMessage public void onMessage(String message, Session session) { if(message.equals(""發送維持連接消息"")){ }else{ 。。。。 } }