1. Disconnect the reason
There are many reasons WebSocket disconnection of the best in the WebSocket disconnection, print out the error.
ws.onclose = function (e) { console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean) console.log(e) }
Error status code:
WebSocket disconnection when triggered CloseEvent
, CloseEvent use WebSockets will be sent to the client when the connection is closed. It uses the WebSocket object onclose event listener. CloseEvent the code field indicates the reason WebSocket disconnection. Causes may be disconnected from the field.
CloseEvent has three fields should be noted, by analyzing these three fields, you can usually find a disconnect reason
CloseEvent.code
: Code is error code is an integer typeCloseEvent.reason
: Reason is the reason for disconnection, a stringCloseEvent.wasClean
: WasClean representation is normally disconnected, it is a Boolean value. When disconnected abnormally general, the value is false
status code | name | description |
---|---|---|
0–999 | Retention period, unused. | |
1000 | CLOSE_NORMAL | Normally closed; no matter what the purpose of creation, the links have completed the task successfully. |
1001 | CLOSE_GOING_AWAY | Terminal leave, probably because the server error, or because the browser to jump from page to open the connection being left. |
1002 | CLOSE_PROTOCOL_ERROR | Since the protocol error interrupted the connection. |
1003 | CLOSE_UNSUPPORTED | Since the type of the received data is not allowed and disconnected (e.g., the terminal receives only the text data received binary data). |
1004 | 保留 Its significance may be defined in the future. |
|
1005 | CLOSE_NO_STATUS | 保留 . I have not received the expected status code. |
1006 |
CLOSE_ABNORMAL | 保留 . For the desired connection closed abnormally received status code (i.e., no transmission frame is closed). |
1007 | Unsupported Data | Since the received data does not match the format disconnected (such as a text message contains a non-UTF-8 data). |
1008 | Policy Violation | Since the received data is non-conforming and disconnected. This is a general status code, use scenarios for an inappropriate status codes 1003 and 1009. |
1009 | CLOSE_TOO_LARGE | Since large data received frames disconnected. |
1010 | Missing Extension | The client agreed on one or more servers expect to expand, but the server does not handle, so the client disconnects. |
1011 | Internal Error | The client encountered due to unexpected circumstances prevented its completion request, so the server is disconnected. |
1012 | Service Restart | Since reboot the server was disconnected. |
1013 | Try Again Later | Due to a temporary reason the server is disconnected, such disconnection overloading the server so clients connecting portion. |
1014 | Retained by the WebSocket standard for future use. | |
1015 | TLS Handshake | Reserved. Indicates that the connection can not be completed because the TLS handshake to close (for example, unable to validate the server certificate). |
1016–1999 | Retained by the WebSocket standard for future use. | |
2000–2999 | Reserved for use by the WebSocket expand. | |
3000–3999 | Can be used by libraries or frameworks.? Should not be. You can register by applications in IANA, first-served basis. | |
4000–4999 | It can be used by the application. |
2. Add heartbeat
var lockReconnect = false; //避免ws重复连接 var ws = null; // 判断当前浏览器是否支持WebSocket var wsUrl = serverConfig.socketUrl; createWebSocket(wsUrl); //连接ws function createWebSocket(url) { try{ if('WebSocket' in window){ ws = new WebSocket(url); } initEventHandle(); }catch(e){ reconnect(url); console.log(e); } } function initEventHandle() { ws.onclose = function () { reconnect(wsUrl); console.log("llws连接关闭!"+new Date().toLocaleString()); }; ws.onerror = function () { reconnect(wsUrl); console.log("llws连接错误!"); }; ws.onopen = function () { heartCheck.reset().start(); //心跳检测重置 console.log("llws连接成功!"+new Date().toLocaleString()); }; ws.onmessage = function (event) { //如果获取到消息,心跳检测重置 heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的 console.log("llws收到消息啦:" +event.data); if(event.data!='pong'){ let data = JSON.parse(event.data); } }; } // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function() { ws.close(); } function reconnect(url) { if(lockReconnect) return; lockReconnect = true; setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多 createWebSocket(url); lockReconnect = false; }, 2000); } //心跳检测 var heartCheck = { timeout: 1000, //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拿到返回的心跳就说明连接正常 ws.send("ping"); console.log("ping!") self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了 ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 }, self.timeout) }, this.timeout) } }
// 收到客户端消息后调用的方法 @OnMessage public void onMessage(String message, Session session) { if(message.equals("ping")){ }else{ 。。。。 } }
系统发现websocket每隔1分钟自动断开连接,搜了很多博客都说设置一下nginx的
proxy_read_timeout
但是这个时间过长会影响服务器性能,采取心跳包的方式每隔1分钟客户端自动发送ping消息给服务端,服务端需要返回pong。即可解决问题。