Manu Artero
Manu Artero

Reputation: 10253

Socket.io: Namespace & WS protocol

Step 1: server

I've created a simple server with Node & Socket.io which declares a namespace under /my-namespace. Once somebody connects, emit a confirmation msg as CONNECT_ACK and emit 3 seconds later another event (for example SOME_EVENT) with a payload:

const express = require('express');
const http = require('http');
const socketIO = require('socket.io');

let app = express();
let server = http.createServer(app);

server.listen(3000, () => {
  console.log('server listening on port 3000');
  let io = new socketIO(server);
  io.of('/my-namespace').on('connection', (socket) => {
    console.log('welcome!');
    socket.emit('CONNECT_ACK');
    setTimeout(() => {
      io.of('/my-namespace').emit('SOME_EVENT', { a: 4 });
    }, 3000);
  });
});

Step 2: client

Then, I created the smallest client side which just connects to the namespace and logs when it receives CONNECT_ACK or SOME_EVENT

<!doctype html>
<html>

<head>
  <title>example</title>
  <script src="./node_modules/socket.io-client/socket.io.js"></script>
  <script>
    const endPoint = "http://localhost:3000/my-namespace";
    io(endPoint)
      .on('CONNECT_ACK', () => { console.log("I've connected"); })
      .on('SOME_EVENT', (data) => { console.dir(data); });
  </script>
</head>

<body>
</body>

</html>

Step 3: Checking everything is awesome

Running the client node index.js and serving the html (I use Python Simple Server) I got the desired in both consoles:

client side

enter image description here

Step 4. Understanding whats going on here

Now, when I opened the Network Chrome tab I started writing this long post. These are the requests:

  1. [WebSocket Protocol]: GET to /socket.io (not to /my-channel) receiving some confirmation bits; POST again to /socket.io including those confirmation bits. OK.
  2. [I don't get this]: again a GET to /socket.io including the confirmation bits which now resolves to the CONNECT_ACK event: ÿ40ÿ40/my-namespaceÿ42/my-namespace,["CONNECT_ACK"]. This is the only event I'm going to receive this way.
  3. [WS]: A GET to /socket.io indicating it's a websoket returns me a 101 (Switching Protocols) and I can recieve the msgs as: 42/my-namespace,["SOME_EVENT",{"a":4}] which is the event I send from the server & some 2s or 3s periodically
  4. [I don't get this too]: again a GET to /socket.io including the confirmation bits which now resolves to this thing: ÿ6

Upvotes: 4

Views: 1346

Answers (1)

Darkhogg
Darkhogg

Reputation: 14165

Why does the client asks for socket.io instead of /my-channel?

When setting up socket.io-server, socket.io will set itself to intercept any request to /socket.io in order to work. Namespaces use the same notation as paths in HTTP, but mean completely different things, and connecting to a namespace performs the same HTTP request to /socket.io, but with a different namespace argument in it.

Why there is a GET after the WS handshake which receives CONNECT_ACK msg?

I can't be sure of this one, but this probably arrived to the server before the WS request, and sent the CONNECT_ACK via polling instead.

Why does all the events start by 42 (I've checked this does not change)

According to this GitHub issue, it defines the packet as a message (4) of type event (2). Personally, I suspect the 4 is actually the protocol version, currently 4, as it's the only reference to that number in the docs except in packet types (which must then be 2).

What is that final GET? is it part of the WS protocol?

Not sure again, but possibly a confirmation that the WS connection has been established and a way for socket.io to confirm that it should switch from polling to WS and start sending the events there.

Upvotes: 1

Related Questions