系统发现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{ 。。。。 } }