He estado tratando de resolver un error de Socket.io realmente extraño.

Si abro la página en el cliente mientras el servidor se está ejecutando, no se conectará con el mensaje:

universalModuleDefinition: 3 Conexión de WebSocket a 'ws: // localhost: 4000 / socket.io /? EIO = 3 & transport = websocket & sid = f6LwPIDZubiPKE-TAAAA' falló: Conexión cerrada antes de recibir una respuesta de reconocimiento

Si luego reinicio el servidor, mientras dejo la página abierta, se conecta sin problemas.

app.js

const app = express();
const server = require('http').Server(app);
require('./socket')(server);

// More code here

server.listen(app.get('port'))

socket.js

const io = require('socket.io');
const jackrabbit = require(`jackrabbit`);
const rabbit = jackrabbit(process.env.RABBIT_URI);
const exchange = rabbit.default();

function Socket (app) {
  this.io = io(app);
  this.io.on('connection', socket => {
    socket.emit('sync');
    socket.on('room', room => {
      socket.join(room);
    });
  })

  this.queue = exchange.queue({ name: 'worker.socket' });
  this.queue.consume(this.onMessage.bind(this), { noAck: true });
}

Socket.prototype.onMessage = function (message) {
  this.io.to(message.report).emit('photo', message.photo);
}

module.exports = function (app) {
  return new Socket(app);
}

cliente

var socket = io.connect();

socket.on('connect', function () {
  // This gets triggered every time (after the error above)
  console.log('Connected');
  // This is never logged by the server
  socket.emit('room', value); // value set by template engine
});

socket.on('sync', function(){
  // will not execute first time I connect, but if I restart
  // the server, it runs no problem
  alert('Synced with server'); 
})

socket.on('photo', function(data) {
  // also will not be run the first time, but works if the
  // server is restarted when the page is open
})

Editar:

Intenté reescribirlo para

  1. Inicialice socket.io dentro de app.js, luego páselo al controlador de socket
  2. Ejecute server.listen antes de requerir socket.js
  3. Inicializar el cliente después de un tiempo de espera
  4. Configurar el método de transporte en el cliente estrictamente en websocket

Ninguno de estos métodos ha funcionado

0
Benedict Lewis 6 dic. 2016 a las 19:15

1 respuesta

La mejor respuesta

Encontré la solución a mi problema (en realidad no es un problema con ninguno de los códigos que publiqué). Estaba usando el middleware compression para Express, que parece romper socket.io. La solución fue agregar lo siguiente:

app.use((req, res, next) => {
  // Disable compression for socket.io
  if (req.originalUrl.indexOf('socket.io') > -1) {
    return next();
  }

  compression()(req, res, next);
});
0
Benedict Lewis 7 dic. 2016 a las 12:43