@devekipers

Добавить переподключение WebSocket?

Как реализовать автоматическое переподключение к вебсокету если соединение упало?

'use strict'

const fs = require('fs')
const https = require('https')
const WebSocketServer = require('ws').Server
const url = require('url')

const key = fs.readFileSync('/var/www/www-root/data/www/comfortapp.online/ws/server/key.pem', 'utf8')
const certificate = fs.readFileSync('/var/www/www-root/data/www/comfortapp.online/ws/server/certificate.pem', 'utf8')

const server = https.createServer({ key, cert: certificate })

const wssControllers = new WebSocketServer({ noServer: true })
const wssDisplays = new WebSocketServer({ noServer: true })

const onUpgrade = (request, socket, head) => {
  const pathname = url.parse(request.url).pathname

  if (pathname === '/' || pathname === '/app') {
    wssControllers.handleUpgrade(request, socket, head, (ws) => wssControllers.emit('connection', ws, request))
  } else if (pathname === '/main') {
    wssDisplays.handleUpgrade(request, socket, head, (ws) => wssDisplays.emit('connection', ws, request))
  } else {
    socket.destroy()
  }
}

const onControllersConnection = (connection) => {
  connection.on('message', onControllerMessage)
}

const onControllerMessage = (message) => {
  try {
    const data = JSON.parse(message)
    if (!data.method) data.method = 'showImage'
    message = JSON.stringify(data)
  } catch (e) {

  }

  for (const client of wssDisplays.clients) {
    client.send(message)
  }
}

wssControllers.on('connection', onControllersConnection)

server.on('upgrade', onUpgrade)
server.listen(3301, '0.0.0.0')
  • Вопрос задан
  • 2018 просмотров
Пригласить эксперта
Ответы на вопрос 2
aagzip
@aagzip
Например так:

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();
Ответ написан
netcrox
@netcrox
Всё время женат
Немного дополню и без того правильный ответ aagzip :)

Действия по оживлению соединения необходимо производить на стороне клиента. Соединение может прерываться в следующих случаях:

  • длительная неактивность вкладки браузера (остановка скрипта)
  • перезагрузка (отключение) сервера
  • проблемы с интернет-соединением


Вот вариант кода на js:

let socket;
let cookieUserId = $.cookie('userId');
let reconnectAttempts = 0;

const MAX_RECONNECT_ATTEMPTS = 100;

function tryToConnect() {

    socket = new WebSocket('wss:// ... /?userId='+cookieUserId); // замените на ваш адрес сервера
    
    socket.onopen = onSocketOpen;
    socket.onmessage = onSocketMessage;
    socket.onclose = onSocketClose;
    socket.onerror = onSocketError;
    
}

function onSocketOpen(e) {

    console.log('Успешное соединение');
    reconnectAttempts = 0; // сбрасываем число попыток при успешном подключении
    ... // ваш код при успешном соединении    

};

function onSocketClose(e) { 

    console.log('Соединение закрыто. Попытка повторного подключения');
    
    if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
        setTimeout(() => tryToConnect(), 2000); // повторное подключение через 1 секунду
        reconnectAttempts++;
    } 
    else {
        console.log('Слишком много попыток соединения. Соединение невозможно, попробуйте позже');
    }

}

function onSocketError(e) { 
    console.log('Ошибка соединения');
    ...
}

function onSocketMessage(e) {
    console.log('You have a new message');
    ...
}

document.addEventListener('DOMContentLoaded', () => {
    tryToConnect(); // начинаем соединение после загрузки DOM
});


Кроме того, для оживления соединения можно слушать окно на активность, примерно так:

window.onfocus = function(){

    console.log('Окно активно');
    
    if (socket.readyState !== 1) { // если за время неактивности окна соединение прервалось
        tryToConnect() // подключаемся заново
    }
    else {
        console.log('Соединение до сих пор активно, повторная попытка не требуется. Статус: ' + socket.readyState)
    }

}


Надеюсь, помог.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы