socket.io: First message never gets sent

For some reason, whenever a new connection is established, the first message I send always seems to go silently ignored. I switched on logging on the Node side, and this is the output:

  engine intercepting request for path "/socket.io/" +14ms
  engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=1444437518880-2&sid=DMd9QzeN3O9frdIRAAAA" +0ms
  engine setting new request for existing client +4ms
  engine:polling setting request +0ms
  engine:socket writing a noop packet to polling for fast upgrade +89ms
  engine:polling writing "�6" +1ms
  engine:ws received "5" +41ms
  engine:socket got upgrade packet - upgrading +1ms
Sending bullshit-message 1
  socket.io-parser encoding packet {"type":2,"data":["bullshit-message","Not seen on client"],"nsp":"/"} +0ms
  socket.io-parser encoded {"type":2,"data":["bullshit-message","Not seen on client"],"nsp":"/"} as 2["bullshit-message","Not seen on client"] +1ms
Sending bullshit-message 2
  socket.io:client writing packet {"type":2,"data":["bullshit-message","THIS will be seen on client"],"nsp":"/"} +10s
  socket.io-parser encoding packet {"type":2,"data":["bullshit-message","THIS will be seen on client"],"nsp":"/"} +10s
  socket.io-parser encoded {"type":2,"data":["bullshit-message","THIS will be seen on client"],"nsp":"/"} as 2["bullshit-message","THIS will be seen on client"] +0ms
  engine:socket sending packet "message" (2["bullshit-message","THIS will be seen on client"]) +10s
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "42["bullshit-message","THIS will be seen on client"]" +0ms
Sending Testing 1! to client DMd9QzeN3O9frdIRAAAA
  socket.io:client writing packet {"type":2,"data":["message","Testing 1!"],"nsp":"/"} +5ms
  socket.io-parser encoding packet {"type":2,"data":["message","Testing 1!"],"nsp":"/"} +4ms
  socket.io-parser encoded {"type":2,"data":["message","Testing 1!"],"nsp":"/"} as 2["message","Testing 1!"] +0ms
  engine:socket sending packet "message" (2["message","Testing 1!"]) +4ms
Sending Testing 2! to client DMd9QzeN3O9frdIRAAAA
  socket.io:client writing packet {"type":2,"data":["message","Testing 2!"],"nsp":"/"} +1ms
  socket.io-parser encoding packet {"type":2,"data":["message","Testing 2!"],"nsp":"/"} +1ms
  socket.io-parser encoded {"type":2,"data":["message","Testing 2!"],"nsp":"/"} as 2["message","Testing 2!"] +0ms
  engine:socket sending packet "message" (2["message","Testing 2!"]) +1ms
  engine:socket flushing buffer to transport +2ms
  engine:ws writing "42["message","Testing 1!"]" +0ms
  engine:ws writing "42["message","Testing 2!"]" +0ms
  engine:ws received "2" +15s
  engine:socket packet +1ms
  engine:socket got ping +0ms
  engine:socket sending packet "pong" (undefined) +0ms
  engine:socket flushing buffer to transport +0ms

It seems like the first message (the bullshit-message, as I’ve come to call it in testing) is encoded, but never actually sent off to the client. What is going on here?

On client:

  engine.io-client:socket changing transport and sending upgrade packet +1ms
  socket.io-1.3.7.js:2 engine.io-client:socket setting transport websocket +1ms
  socket.io-1.3.7.js:2 engine.io-client:socket clearing existing transport polling +1ms
  socket.io-1.3.7.js:2 engine.io-client:polling ignoring poll - transport state "paused" +1ms
  socket.io-1.3.7.js:2 engine.io-client:socket socket receive: type "message", data "2["bullshit-message","THIS will be seen on client"]" +10s
  socket.io-1.3.7.js:1 socket.io-parser decoded 2["bullshit-message","THIS will be seen on client"] as %j +9s Object {type: 2, nsp: "/", data: Array[2]}
  socket.io-1.3.7.js:1 socket.io-client:socket emitting event %j +9s ["bullshit-message", "THIS will be seen on client"]
Bullshit data received THIS will be seen on client
  socket.io-1.3.7.js:2 engine.io-client:socket socket receive: type "message", data "2["message","Testing 1!"]" +5ms
  socket.io-1.3.7.js:1 socket.io-parser decoded 2["message","Testing 1!"] as %j +5ms Object {type: 2, nsp: "/", data: Array[2]}
  socket.io-1.3.7.js:1 socket.io-client:socket emitting event %j +5ms ["message", "Testing 1!"]
Data received Testing 1!
  socket.io-1.3.7.js:2 engine.io-client:socket socket receive: type "message", data "2["message","Testing 2!"]" +8ms
  socket.io-1.3.7.js:1 socket.io-parser decoded 2["message","Testing 2!"] as %j +8ms Object {type: 2, nsp: "/", data: Array[2]}
  socket.io-1.3.7.js:1 socket.io-client:socket emitting event %j +8ms ["message", "Testing 2!"]
Data received Testing 2!

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 16 (8 by maintainers)

Most upvoted comments

Digging into this a bit more, I believe something strange is going on with the onopen event. Here is the order of events I’m seeing in the browser:

  • socket.client-io establishes WebSocket connection to server
  • socket.client-io fires onopen event
  • socket.client-io emits my first event (in this case login)
  • engine.io fires onopen event
  • engine.io receives ping events from server
  • engine.io receives first response from server

Why is socket.client-io firing the onopen event before the engine.io has emitted it?

UPDATE: I was able to solve my problem by changing:

import io from 'socket.io-client';

// Instead of
this.socket = new io(BASE_URL);

// I now initialize the Socket.IO client class as:
this.socket = new io(BASE_URL, {transports: ['websocket']});

By default transports seems to be set to ['polling', 'websocket']. I have no idea what polling is or what the transports option does (documentation for this is very hard to find). But it seems to solve my problem. I now consistently see my requests sent and received.

Any ideas? Same issue

require('log-timestamp');
const   app = require('express')(),
        http = require('http').Server(app),
        io = require('socket.io')(http),
        path = require('path');

app.get('/client', function(req, res) {
    res.sendFile(path.join(__dirname + '/index.html'));
});

http.listen(8080, function(){});
io.on('connection', function (socket) {
    socket.emit('immediate',{'some' : 'data'});  //never received in browser
    setTimeout(() => {
        socket.emit('deferred',{'some' : 'some'}); //always received in browser
    },1500);
});

what i’ve pointed out is that at emmititing ‘immediate’ event the socket.client.Client.conn.socket.upgraded is false, but after 1.5s that is true, and all works just fine

Same issue here, please find a fix!

update: rather than applying a timeout, process.nextTick seems a better solution