Клиент socketio молча теряет соединение и создает новый сокет (транспортный конец)

Я работаю над анимацией ThreeJS, которая записывается с помощью ccapture

это зависит от того, что каждый клиент имеет одно соединение с бэкендом узла, который получает событие сокета 'render-frame'.

Это работает некоторое время, но через несколько минут клиент без ошибок закрывает соединение без вывода сообщений, а затем создает новое соединение, теряя тем самым первое начальное соединение с сокетом. Я держу окно открытым все время и в фокусе.

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

socket.io:socket emitting event ["render-frame",{"frame":168}] +0ms
render frame
{ frame: 168 }
socket.io:client client close with reason transport close +6ms
socket.io:socket closing socket - reason transport close +0ms
socket.io:client ignoring remove for fbD1a4Wx0jBzJ7hqAAAA +1ms
SOCKET DISCONNECTED!

Я упростил мой слушатель рендеринга фрейма на моем узле для отладки, и сейчас он просто выглядит так:

io.on("connection", function (socket) {
    socket.on("disconnect", function (socket) {
        console.log("SOCKET DISCONNECTED!");
    });
    socket.on("render-frame", function (data) {
        console.log(data);
    });
});

Это происходит во всех браузерах, хотя мне действительно нужно, чтобы он работал в Chrome. Использование socket.io 1.3.7

Любая помощь в отношении причины ошибки "Транспортное закрытие" будет принята с благодарностью.

2 ответа

Я думаю, что вы должны посмотреть на этот вопрос: соединения NodeJS + Socket.io обрывается / переподключается?

Ваша проблема заключается в тайм-аутах сокетов. Если на определенном сокете нет активности, 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});
});

Похоже, что HackTimer.js и ccapture.js заменяют window.setTimeout пользовательской функцией. HackTimer.js, кажется, работает нормально, если он выполняется раньше, чем любой другой JavaScript. Для ccapture.js вы можете попытаться убедиться, что он запускается как первый скрипт. Итак, SocketIO сначала использует родной setTimeout вашего браузера, который затем сдувается с помощью пользовательского setTimeout, который ломает любой из работающих в настоящее время таймеров.

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