WebSocket disconnection cause, the heartbeat mechanism is automatically disconnected to prevent

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 type
  • CloseEvent.reason: Reason is the reason for disconnection, a string
  • CloseEvent.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。即可解决问题。

 

Guess you like

Origin www.cnblogs.com/gxp69/p/11736749.html