developer tip

WebSocket에서 서버 재부팅시 클라이언트 재 연결

copycodes 2020. 9. 15. 07:58
반응형

WebSocket에서 서버 재부팅시 클라이언트 재 연결


PHP5와 Chrome 브라우저를 클라이언트로 사용하는 웹 소켓을 사용하고 있습니다. http://code.google.com/p/phpwebsocket/ 사이트에서 코드를 가져 왔습니다 .

나는 서버를 실행하고 클라이언트도 연결됩니다. 채팅도 할 수 있습니다. 이제 서버를 다시 시작하면 (종료하고 다시 시작하여) 클라이언트는 연결이 끊어진 정보를 얻지 만 메시지를 보낼 때 자동으로 서버에 다시 연결하지 않습니다.

이것을 달성하는 방법? 연결이 끊긴 정보를 받았을 때처럼 확인하고 JavaScript로 보내 페이지를 새로 고치거나 다시 연결해야합니까?


서버가 재부팅되면 웹 소켓 연결이 닫히고 JavaScript onclose이벤트가 트리거됩니다. 다음은 5 초마다 다시 연결을 시도하는 예입니다.

function start(websocketServerLocation){
    ws = new WebSocket(websocketServerLocation);
    ws.onmessage = function(evt) { alert('message received'); };
    ws.onclose = function(){
        // Try to reconnect in 5 seconds
        setTimeout(function(){start(websocketServerLocation)}, 5000);
    };
}

Andrew가 제공 한 솔루션은 완벽하게 작동하지 않습니다. 연결이 끊어진 경우 서버가 여러 개의 닫기 이벤트를 보낼 수 있기 때문입니다.

이 경우 여러 setTimout을 설정합니다. Andrew가 제공 한 솔루션은 서버가 5 초 전에 준비된 경우에만 작동 할 수 있습니다.

그런 다음 Andrew 솔루션을 기반으로 재 작업하여 창 개체에 ID를 연결하는 setInterval을 사용했습니다 (이렇게하면 "모든 곳에서"사용할 수 있음).

var timerID=0;

var socket;

/* Initiate what has to be done */

socket.onopen=function(event){
 /* As what was before */
 if(window.timerID){ /* a setInterval has been fired */
   window.clearInterval(window.timerID);
   window.timerID=0;
 }
 /* ... */
}

socket.onclose=function(event){
  /* ... */
 if(!window.timerID){ /* Avoid firing a new setInterval, after one has been done */
  window.timerID=setInterval(function(){start(websocketServerLocation)}, 5000);
 }
 /* That way, setInterval will be fired only once after losing connection */
 /* ... */
}

WebSocket 다시 연결

GitHub는 WebSocket API를 장식하는 작은 JavaScript 라이브러리를 호스팅하여 연결이 끊어지면 자동으로 다시 연결되는 WebSocket 연결을 제공합니다.

gzip 압축을 사용하는 축소 된 라이브러리는 600 바이트 미만입니다.

공식 저장소는 여기에서 사용할 수 있습니다.

https://github.com/joewalnes/reconnecting-websocket

서버 홍수

If a high number of clients are connected to the server when it reboots. It may be worthwhile to manage the reconnect timings of the clients by using an Exponential Backoff algorithm.

The algorithm works like this:

  1. For k attempts, generate a random interval of time between 0 and 2^k - 1,
  2. If you are able to reconnect, reset k to 1,
  3. If reconnection fails, k increases by 1 and the process restarts at step 1,
  4. To truncate the max interval, when a certain number of attempts k has been reached, k stops increasing after each attempt.

Référence:

http://blog.johnryding.com/post/78544969349/how-to-reconnect-web-sockets-in-a-realtime-web-app

ReconnectingWebSocket does not handle reconnections by using this algorithm.


I have been using this patten for a while for pure vanilla JavaScript, and it supports a few more cases than the other answers.

document.addEventListener("DOMContentLoaded", function() {

  'use strict';

  var ws = null;

  function start(){

    ws = new WebSocket("ws://localhost/");
    ws.onopen = function(){
      console.log('connected!');
    };
    ws.onmessage = function(e){
      console.log(e.data);
    };
    ws.onclose = function(){
      console.log('closed!');
      //reconnect now
      check();
    };

  }

  function check(){
    if(!ws || ws.readyState == 3) start();
  }

  start();

  setInterval(check, 5000);


});

This will retry as soon as the server closes the connection, and it will check the connection to make sure it's up every 5 seconds also.

So if the server is not up when this runs or at the time of the onclose event the connection will still come back once it's back online.

NOTE: Using this script will not allow you to ever stop trying to open a connection... but I think that's what you want?


Below are the codes i have used in my project which working 100%.

  1. Put all the websocket code inside the init function.
  2. Inside the onclose callback call the init again.
  3. Finally call the init function inside the document ready function.

var name = sessionStorage.getItem('name');

wsUri =  "ws://localhost:8080";   
var websocket;
$(function() {  
    init();  
    $("#chat_text_box").on("keypress", function(e) {         
        if (e.keyCode == 13) {   //For Enter Button    
            e.preventDefault();
            var mymessage = $('#chat_text_box').val();               
            if(mymessage){
                var msg = {  type: 'chat_text',  data : {  name:name,  msg:mymessage }  };                
                console.log(msg);
                websocket.send(JSON.stringify(msg));
                $('#chat_text_box').val('');
            }               
            return false;                       
        }        
    });      
});     
function init() { 
    websocket = new WebSocket(wsUri);      
    websocket.onopen = function(ev) { /*connection is open */    } 
    websocket.onmessage = function(ev) {        
        var data = JSON.parse(ev.data); //PHP sends Json data        
        var type = data.type;//alert(JSON.stringify(data));
        switch(type) {
            case "chat_text":
                var text = "<div><span class='user'>"+data.data.sender_name+" : </span><span class='msg'>"+data.data.msg+"</span></div>";
                $('#chat-messages').append(text);
                break;            
            default:
                break;

        }        

    };     
    websocket.onerror   = function(ev){}; 
    websocket.onclose = function(ev) {   init();   };  
}

Can't comment, but the following:

var socket;

const socketMessageListener = (event) => {
  console.log(event.data);
};

const socketOpenListener = (event) => {
  console.log('Connected');
  socket.send('hello');
};

const socketCloseListener = (event) => {
  if (socket) {
    console.error('Disconnected.');
  }
  socket = new WebSocket('ws://localhost:8080');
  socket.addEventListener('open', socketOpenListener);
  socket.addEventListener('message', socketMessageListener);
  socket.addEventListener('close', socketCloseListener);
};

socketCloseListener();

// for testing
setTimeout(()=>{
  socket.close();
},5000);

Plus https://www.npmjs.com/package/back is already good enough :)

참고URL : https://stackoverflow.com/questions/3780511/reconnection-of-client-when-server-reboots-in-websocket

반응형