Невозможно создать стабильную реализацию веб-сокета

Сценарий использования: Это работает на стороне сервера (Keystone) приложения Android.

  • Приложение подключается к сокету с доступом пользователя
  • Приложение показывает индикаторы для всех остальных пользователей, подключенных к розетке.
  • Когда пользователь изменяет некоторые данные в приложении, принудительное обновление отправляется через сокет всем «онлайн» пользователям, чтобы они знали, что нужно получить самые свежие данные.

Главная проблема:

  • Он работает до тех пор, пока клиент не теряет подключение к Интернету прямо между интервалами. Затем соединение сокета закрывается и больше не открывается.

Я не знаю, проблема в моей реализации или проблема в реализации на стороне клиента.

В реализации используются:

Вот реализация на сервере:

const clients = {};
let wss = null;

const delimiter = '_';

/**
 * Clients are stored as "companyId_deviceId"
 */
function getClients() {
  return clients;
}

function sendMessage(companyId, msg) {
  try {
    const clientKey = Object.keys(clients).find((a) =>     a.split(delimiter)[0] === companyId.toString());

    const socketForUser = clients[clientKey];
    if (socketForUser && socketForUser.readyState === WebSocket.OPEN) {
      socketForUser.send(JSON.stringify(msg));
    } else {
      console.info(`WEBSOCKET: could not send message to company ${companyId}`);
    }
  } catch (ex) {
    console.error(`WEBSOCKET: could not send message to company     ${companyId}: `, ex);
  }
}

function noop() { }

function heartbeat() {
  this.isAlive = true;
}

function deleteClient(clientInfo) {
  delete clients[`${clientInfo.companyId}${delimiter}${clientInfo.deviceId}`];

  // notify all clients
  forceRefreshAllClients();
}

function createSocket(server) {
  wss = new WebSocket.Server({ server });

  wss.on('connection', async (ws, req) => {
    try {
      // verify socket connection
      let { query: { accessToken } } = url.parse(req.url, true);
      const decoded = await tokenHelper.decode(accessToken);

      // add new websocket to clients store
      ws.isAlive = true;
      clients[`${decoded.companyId}${delimiter}${decoded.deviceId}`] = ws;
      console.info(`WEBSOCKET: ➕ Added client for company ${decoded.companyId} and device ${decoded.deviceId}`);

      await tokenHelper.verify(accessToken);

      // notify all clients about new client coming up
      // including the newly created socket client...
      forceRefreshAllClients();

      ws.on('pong', heartbeat);
    } catch (ex) {
      console.error('WEBSOCKET: WebSocket Error', ex);
      ws.send(JSON.stringify({ type: 'ERROR', data: { status: 401, title: 'invalid token' } }));
    }

    ws.on('close', async () => {
      const location = url.parse(req.url, true);
      const decoded = await tokenHelper.decode(location.query.accessToken);

      deleteClient({ companyId: decoded.companyId, deviceId: decoded.deviceId });
   });
});

  // Ping pong on interval will remove the client if the client has no internet connection
  setInterval(() => {
    Object.keys(clients).forEach((clientKey) => {
      const ws = clients[clientKey];
      if (ws.isAlive === false) return ws.terminate();

      ws.isAlive = false;
      ws.ping(noop);
    });
  }, 15000);
}

function forceRefreshAllClients() {
  setTimeout(function () {
    Object.keys(clients).forEach((key) => {
      const companyId = key.split(delimiter)[0];
      sendMessage(companyId, createForcedRefreshMessage());
    });
  }, 1000);
}

У клиентов также должен быть setInterval для проверки подключения к серверу и повторного подключения, если он не работает.

mihai 22.10.2018 22:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
212
0

Другие вопросы по теме