웹소켓 재연결 메커니즘 실현

3798 단어
약한 네트워크 환경이나 네트워크가 일시적으로 끊어진 상황에서 우리는 네트워크가 불안정할 때 클라이언트와 서비스 측이 다시 연결되고 계속 통신할 수 있도록 안정적인 재연결 메커니즘을 필요로 한다.본고는 웹소켓 프로토콜의 재연결 메커니즘에 대해 상세하게 설명할 것이다.

생각


실례화된 웹socket 후, 우리는 각 리셋 이벤트가 실행해야 할 함수를 정의할 것이다
var ws = new WebSocket(url);
ws.onclose = function () {
    // 
};
ws.onerror = function () {
    // 
};
ws.onopen = function () {
    // 
};
ws.onmessage = function (event) {
    // 
}

약한 네트워크 환경에서 메시지를 보내면 수신단에 도착할 수 없다.또는 브라우저의 약정 시한까지 인터넷을 끊는 등 일부 이상 상황은 onclose와 onerror를 촉발하기 때문에 이론적으로 우리는 onclose와 onerror를 연결할 때 긴 연결을 다시 만들면 된다.

실현


위의 간단한 사고방식에 따라 코드는 다음과 같다.
var ws = new WebSocket(url);
ws.onclose = function () {
  reconnect()
};
ws.onerror = function () {
  reconnect()
};

function reconnect(url) {
    setTimeout(function () {     // , 
      var ws = new WebSocket(url);
      ws.onclose = function () {
        reconnect()
      };
      ws.onerror = function () {
        reconnect()
      };
    }, 2000);
}

조금만 추출하고 풍부하게,createWebSocket은 웹socket 실례를 만들고, initEventHandle은 각 리셋 함수를 연결합니다.
var ws = new WebSocket(url);
ws.onclose = function () {
  reconnect()
};
ws.onerror = function () {
  reconnect()
};

//  
function reconnect(url) {
    setTimeout(function () {     // , 
      createWebSocket(url);
    }, 2000);
}

//  websocket
function createWebSocket(url) {
    try {
        if ('WebSocket' in window) {
            ws = new WebSocket(url);
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(url);
        } else {
            _alert(" websocket , ",3000)
        }
        initEventHandle();
    } catch (e) {
        reconnect(url);
    }
}

//  
function initEventHandle() {
    ws.onclose = function () {
        reconnect(wsUrl);
    };
    ws.onerror = function (err) {
        reconnect(wsUrl);
    };
}

최적화


약한 네트워크, 연결이 끊어지면 다시 연결되는 것은 수동적인 것이고 일반적인 웹socket 연결에는 심장 박동 메커니즘이 존재한다. 클라이언트와 서비스 측은 특정한 심장 박동 메시지를 약속하여 체인이 정상적으로 통신하는지 검사하는 데 사용한다.우리는 심장 박동 메커니즘을 통해 클라이언트가 체인의 정상을 측정하고 약정된 시간 간격 내에 심장 박동이나 다른 통신 메시지를 받지 못할 때 클라이언트가 주동적으로 다시 연결한다.따라서 다음 최적화된 방법은 심장 박동 측정 방법을 추가해야 한다.
var heartCheck = {
    timeout: heartBeatTime*1000,  //   
    timeoutObj: null, //  
    reset: function () { //  
        clearTimeout(this.timeoutObj);
        return this;
    },
    start: function () { //  
        var self = this;
        this.timeoutObj = setTimeout(function () {
          //  , , 
            ws.close();
        },this.timeout)
    }
}

하트비트 체크 객체, 정의됨
  • timeout: 심장 박동 시간 초과
  • timeoutObj: 타이머 변수
  • reset: 심장 박동 초기화
  • start: 심장 박동 열기 연결 성공 시 심장 박동 열기;메시지를 받았을 때 심장박동을 초기화하고 다음 검사를 열기 때문에 우리는 onopen과 onmessage에 심장박동 검사를 추가하면 됩니다
  • //  
    function initEventHandle() {
        ws.onclose = function () {
            reconnect(wsUrl);
        };
        ws.onerror = function (err) {
            reconnect(wsUrl);
        };
        ws.onopen = function () {
            heartCheck.reset().start();      // 
        };
        ws.onmessage = function (msg) {    // , 
            heartCheck.reset().start();      // 
            handleMsg(msg)
        };
    }
    

    동시에 여러 차례 중련된 문제를 일으키다


    실제 사용 과정에서 일부 브라우저를 발견하면reconnect 리셋은 여러 번 터치할 수 있기 때문에 리셋에 자물쇠를 추가해야 합니다. 리셋이 실행 중일 때 다시 터치할 수 없습니다.
    function reconnect(url) {
        if (reconnect.lockReconnect) return;
        reconnect.lockReconnect = true;
        setTimeout(function () {     // , 
            createWebSocket(url);
            reconnect.lockReconnect = false;
        }, 2000);
    }
    

    같은 브라우저에서 여러 페이지가 하나의 연결로 통신을 하려면 브라우저 캐시/데이터 루트 (local Storage/indexed DB) 를 사용하여 이 자물쇠를 추가해야 합니다.

    참고


    1, MDN Websockt 2, 웹소켓 심박수 재연결 초기 탐색 및 구현

    좋은 웹페이지 즐겨찾기