NodeJS + Socket.io соединения сбрасываются / переподключаются?

В производстве у меня есть игра, которая использует локальные переменные соединения для хранения состояния игры. Тем не менее, я замечаю, что, если я в течение определенного времени бездействую в соединении, оно отключается и повторно соединяется, что теряет текущее состояние. Во время моих тестов на локальном хосте я никогда не замечал такого поведения. Является ли это нормальным поведением для соединений с сокетами или что-то еще, вызывающее разрыв соединений.

Если это нормальное поведение, как это обычно обрабатывается? Должны ли значения соединения храниться глобально, чтобы их можно было восстановить, если пользователь отбросит / переподключится?

2 ответа

Решение

Ваша проблема заключается в тайм-аутах сокетов. Если на определенном сокете нет активности, socket.io закроет его автоматически.

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

Сервер:

function sendHeartbeat(){
    setTimeout(sendHeartbeat, 8000);
    io.sockets.emit('ping', { beat : 1 });
}

io.sockets.on('connection', function (socket) {
    socket.on('pong', function(data){
        console.log("Pong received from client");
    });
}

setTimeout(sendHeartbeat, 8000);

Клиент:

socket.on('ping', function(data){
      socket.emit('pong', {beat: 1});
    });

Дополнительная информация:

Вы можете получить больше информации о настройке socket.io здесь.

РЕДАКТИРОВАТЬ: Марк прокомментировал, что если пользователь теряет соединение (соединение обрывается на его конце из-за проблем с интернетом), вы сможете восстановить пользователя до его последнего состояния.

Для этого лучше всего использовать уже широко используемый метод хранения пользовательских данных, файлов cookie и сеансов.

Очень хорошо сделанный урок о том, как это сделать, находится здесь. Хотя он использует Express для установки файлов cookie, вы можете сделать это с помощью чего угодно (я делаю это с помощью rails). Используя этот метод, вы можете сохранить пользовательские данные в файле cookie и извлечь их во время рукопожатия. Оттуда вы можете просто получить доступ к данным, используя socket.handshake.data,

Что вам нужно сделать, это создать или идентифицировать сеанс для (повторного) соединения. Вы можете уменьшить количество переподключений в ответе Moox, приведенном выше, но он все еще не является отказоустойчивым - например, пользователь теряет соединение Wi-Fi на некоторое время и т. Д. Другими словами - поддерживает метаданные пользователя для сеанса, а не для сокета, и ожидает случайных отключений и повторных подключений.,

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