جاوااسکریپت - وبسوکت: چگونه پس از قطع شدن بهطور خودکار دوباره متصل شویم


var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function () {
  ws.send(JSON.stringify({
      .... some message the I must send when I connect ....
  }));

};

ws.onmessage = function (e) {
  console.log('Got a message')
  console.log(e.data);
};

ws.onclose = function(e) {  
  console.log('socket closed try again'); 

}

ws.onerror = function(err) {
  console.error(err)
};

وقتی برای اولین بار به سوکت متصل میشوم، ابتدا باید پیامی به سرور ارسال کنم تا خودم را احراز هویت کرده و به کانالها اشتراک پیدا کنم.

مشکلی که من دارم این است که گاهی سرور سوکت غیرقابل اعتماد است و این باعث فعال شدن رویدادهای onerror و onclose شیء 'ws' میشود.

سؤال: یک الگوی طراحی خوب که به من اجازه دهد هر زمان که سوکت بسته شد یا با خطا مواجه شد، 10 ثانیه صبر کنم و سپس دوباره به سرور سوکت متصل شوم (و پیام اولیه را دوباره به سرور ارسال کنم) چیست؟

پاسخ شماره ۱

این چیزی است که در نهایت با آن به نتیجه رسیدم. برای اهداف من کار میکند.

function connect() {
  var ws = new WebSocket('ws://localhost:8080');
  ws.onopen = function() {
    // subscribe to some channels
    ws.send(JSON.stringify({
        //.... some message the I must send when I connect ....
    }));
  };

  ws.onmessage = function(e) {
    console.log('Message:', e.data);
  };

  ws.onclose = function(e) {
    console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
    setTimeout(function() {
      connect();
    }, 1000);
  };

  ws.onerror = function(err) {
    console.error('Socket encountered error: ', err.message, 'Closing socket');
    ws.close();
  };
}

connect();

پاسخ شماره ۲

این برای من با setInterval کار کرد، زیرا اتصال مشتری ممکن است از دست برود.

ngOnInit(): void {
    if (window.location.protocol.includes('https')) {
        this.protocol = 'wss';
    }

    this.listenChanges();
}


listenChanges(): void {
    this.socket = new WebSocket(`${this.protocol}://${window.location.host}/v1.0/your/url`);

    this.socket.onmessage = (event): void => {
        // your subscription stuff
        this.store.dispatch(someAction);
    };

    this.socket.onerror = (): void => {
        this.socket.close();
    };


    this.socket.onopen = (): void => {
        clearInterval(this.timerId);

        this.socket.onclose = (): void => {
            this.timerId = setInterval(() => {
                this.listenChanges();
            }, 10000);
        };
    };
}

فراموش نکنید که وقتی سوکت باز شد، clearInterval را صدا بزنید.