Розетки не убираются после отключения - PullRequest
0 голосов
/ 14 января 2019

У меня есть особая проблема, которую я пытаюсь исправить. На сервере у меня есть следующий код ...

// Establish a connection with a WebSocket.
io.on("connection", socket => {

  setTimeout(sendHeartbeat, 25000);

  function sendHeartbeat(){
    setTimeout(sendHeartbeat, 25000);
    io.sockets.emit("ping", socket.id);
    console.log(io.sockets.adapter.rooms);
  }

});

Происходит следующее: я каждые 25 секунд проверяю клиент на всех существующих сокетах и ​​отправляю идентификатор сокета подключенного клиента.

На стороне клиента я просто слушаю результат и печатаю его на консоли ...

socket.on('ping',function(data) {
  console.log(data);
});

Я запускаю свой сервер, и соединение установлено, на сервере у меня есть следующее ...

{ QofufgzXeTqGJcLOAAAA: Room { sockets: { QofufgzXeTqGJcLOAAAA: true }, length: 1 } }

Это правильно, поскольку существует только 1 соединение, однако на стороне клиента консоль каждые 25 секунд выглядит следующим образом ...

undefined
QofufgzXeTqGJcLOAAAA

Не уверен, откуда исходит undefined.

Я продолжаю позволять серверу работать, в конце концов сокет отключается, а затем снова подключается (это происходит время от времени), в этом случае старый сокет должен быть удален и заменен новым, и это именно то, что происходит на сервер ...

{ o2UFD7iHNxc94bPHAAAB: Room { sockets: { o2UFD7iHNxc94bPHAAAB: true }, length: 1 } }

Но на стороне клиента каждые 25 секунд печатается следующее ...

undefined
QofufgzXeTqGJcLOAAAA
o2UFD7iHNxc94bPHAAAB

Я пытаюсь понять, почему старые сокеты не удаляются. При каждом отключении, кажется, добавляется дополнительный сокет. Как я могу это исправить? В приведенных выше примерах на консоль должен выводиться только один идентификатор сокета.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Решение, которое работало для меня, заключалось в использовании setInterval с clearInterval. Причина, по которой я получаю несколько сокетов, выводимых на консоль, заключается в том, что рекурсивная функция никогда не очищается, и поэтому все экземпляры выполняются вместе асинхронно.

Мое новое решение следующее ...

// Ping the client to prevent disconnect.
let keepAlive = setInterval(sendHeartbeat, 25000);
function sendHeartbeat(){
    io.sockets.emit("ping", socket.id);
    console.log(io.sockets.adapter.rooms);
}

... и при отключении я делаю ...

socket.on("disconnect", async () => {
  clearInterval(keepAlive);
});

Это решило мою проблему, и теперь я получаю только 1 сокет на консоль, как и ожидалось. Я все еще получаю undefined один, но чтобы решить, что этот ответ объясняет, как решить проблему.

По существу, socket.io требуется некоторое время для установления соединения, поэтому socket.on('connection', ...) может использоваться для проверки, установлено ли соединение. Это удалит undefined из консоли.

0 голосов
/ 14 января 2019

Вы можете либо изменить это значение на io.once("connection"), что будет означать, что при каждом подключении к нему не добавляется дополнительная привязка, или вы можете подписаться на событие отключения и отсоединиться от этого события при разрыве подключения. Я склоняюсь к второму подходу, так как он приводит к более чистому коду и меньшему количеству моментов позже

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...