3

I've been looking around for a definitive answer to this but I seem to keep finding contradictory answers (ex this and this).

Basically, if I

socket.emit('game_update', {n: 1});

from a node.js server and then, 20 ms later,

socket.emit('game_update', {n: 2});

from the same server, is there any way that the n:2 message arrives before the n:1 message? In other words, does the n:1 message "block" the receiving of the n:2 message if the n:1 message somehow got lost on the way?

What if they were volatile emits? My understanding is that the n:1 message wouldn't block the n:2 message -- if the n:1 message got dropped, the n:2 message would still be received whenever it arrived.

Background: I'm building a node.js game server and want to better understand how my game updates are traveling. I'm using volatile emit right now and I would like to increase the server's tick rate, but I want to make sure that independent game updates wouldn't block each other. I would rather the client receive an update every 30 ms with a few dropped updates scattered here and there than have the client receive an update, receive nothing for 200 ms, and then receive 6 more updates all at once.

Community
  • 1
  • 1
Victor Zhou
  • 423
  • 3
  • 14

2 Answers2

1

Disclaimer: I'm not completely familiar with the internals of socket.io.

is there any way that the n:2 message arrives before the n:1 message?

It depends on the transport that you're using. For the polling transport, I think it's fair to say that it's perfectly possible for messages to arrive out-of-order, because each message can arrive over a different connection.

With the websocket transport, which maintains a persistent connection, the message order is reasonably guaranteed.

What if they were volatile emits?

With volatile emits, all bets are off, it's fire-and-forget. I think that in normal situations, the server will wait (and queue up messages) for a client to be ready to receive messages, unless those messages are volatile, in which case the server will just drop them.

From what you're saying, I think that volatile emits are what you want, although once a websocket connection has been established I don't think you'll see the described scenario ("receive an update, receive nothing for 200 ms, and then receive 6 more updates all at once") is likely to happen. Perhaps only when the connection gets lost and is re-established.

robertklep
  • 198,204
  • 35
  • 394
  • 381
0

The answer is yes it can possibly arrive later, but it is highly unlikely given that sockets are by nature persistent connections and reliability of order is all but guaranteed.

According to the Socket.io documentation messages will be discarded in the case that the client is not connected. This doesn't necessarily fit with your use case, however within the documentation itself it describes Volatile events as an interesting example if you need to send the position of a character.

// server-side
io.on("connection", (socket) => {
  console.log("connect");

  socket.on("ping", (count) => {
    console.log(count);
  });
});

// client-side
let count = 0;
setInterval(() => {
  socket.volatile.emit("ping", ++count);
}, 1000);

If you restart the server, you will see in the console:

connect
1
2
3
4
# the server is restarted, the client automatically reconnects
connect
9
10
11

Without the volatile flag, you would see:

connect
1
2
3
4
# the server is restarted, the client automatically reconnects and sends its 
buffered events
connect
5
6
7
8
9
10
11

Note: The documentation explicitly states that this will happen during a server restart, meaning that your connection to the client likely has to be lost in order for the volatile emits to be dropped.

I would say a good practice would be to write your emits as volatile just in case you do get a dropped client, however this will depend heavily on your game requirements.

As for the goal, I would recommend that you use client side prediction using some sort of dynamic time system or deltatime based on the client and server keeping a sync clock to help alleviate some of the problems you can incur. Here's an example of how you can do that, though I'm not a fan of the creators syntax, it can be easily adapted to your needs.

Hope this helps anyone who hits this topic.

Socket.io - Volatile events

Client Side Prediction

Andrew
  • 399
  • 6
  • 15