Express: Node.js how to use socket.io in express route

So if I understand correctly, express.js handles all the HTTP/HTTPS request and Socket.io does handle all the interactions regarding websockets. So these are 2 entities which are completely separated. After the application is started the express part is listening to http requests, while the socket.io part is listening for websocket events or connects (connecting is done with HTTP , the websocket handshake using HTTP headers). Because the express instance and the socket.io instance share the same HTTP server they can use the same TCP connection .

Currently working on a Node.JS backend which uses both express.js and Socket.io . The basis of the application looks something like this:


Solution:

To understand how this works under the covers, you really have to understand how a socket.io connection works and then you can see how it is related to your http server.

  1. A default socket.io connection starts with a couple http requests. This is how the socket.io client negotiates with the server to decide exactly what both can support. These http requests go to your node.js web server (the same one you’re using for Express). A socket.io-inserted request handler intercepts these requests and handles them so they are not sent to your Express routes.
  2. After a couple http requests like the above one, if both sides agree that a webSocket connection can be made as the base transport for the ongoing socket.io connection, then the socket.io client sends a special http request to the server with a few custom headers.
  3. The http server (again the same one you’re using for Express) receives this special http request and the socket.io server code again intercepts that request and handles it. In this case, it responds to this special http request with an “upgrade” to the webSocket protocol and the socket that started out as an http request is converted to the webSocket protocol and becomes a long-lived socket that speaks only the webSocket protocol.
  4. At this point, the http web server is no longer involved in further communications. The socket that started life as an http request has been handed off to the socket.io server code and that socket is now speaking the webSocket protocol. At this point either client or server can send messages over that socket and they will be received by the appropriate code at the other end.
  5. Now, socket.io actually uses a layer on top of webSocket. While the underlying data packets are formatted for the webSocket protocol, socket.io adds its own application layer on top of webSocket which means that you must have socket.io code on both ends for this to work (a socket.io client can’t talk to a plain webSocket server or vice versa).

So if I understand correctly, express.js handles all the HTTP/HTTPS request and Socket.io does handle all the interactions regarding websockets.

Sort of. The http server (that underlies Express) handles all incoming http requests. This includes normal http requests that will be routed through Express, but it also includes http requests that are related to opening and establishing a socket.io connection. Those special requests are handled by an http server request handler inserted by socket.io and not passed down the line for Express to handle.

So these are 2 entities which are completely separated.

There’s one http server and then some request handlers that decide if Express should process the request or if socket.io should process the request. Once, the request has been passed off to one of the other, they are pretty much separate.

But, there are some points where they can intersect. For example, if you are using a session manager with Express that sets a session cookie or any other type of code that sets cookies, then those cookies are available to socket.io connections too. So, with the right supporting code, a socket.io connection can access a session object (or other cookies) created by your Express middleware or request handlers. Remember, a socket.io connection starts with an http request so any cookies that the browser would normally send with an http request will be there for the socket.io request too.

After the application is started the express part is listening to http requests, while the socket.io part is listening for websocket events or connects (connecting is done with HTTP, the websocket handshake using HTTP headers).

As I said above, the http server is listening for incoming http requests and both socket.io and Express have request handlers that look at those incoming requests and decide if they should participate in handling that request or not. Some incoming requests are directed to the socket.io server code and some are directed to the express route handlers.

Because the express instance and the socket.io instance share the same HTTP server they can use the same TCP connection.

They don’t really share a TCP connection. There is one shared http server that listens for incoming http requests. Those requests are then routed either to socket.io code or express code for further processing based on data in the request. If it’s a socket.io request to initiate a socket.io connection, then that TCP socket is “upgraded” to the webSocket protocol and only socket.io server code handles that TCP socket from then one. If it’s not a socket.io request, then the http request is passed on to Express code and it decides what to do with it based on the middleware and routes defined.

Is my above described current understanding correct?

Partially correct, partially not correct. Lots of details above.

Can these 2 entities interact with each other, if so in what way(s)?

They share the http server. They share access to cookies.

With the right server-side code, it’s possible to have an http request (typically an Ajax call from an already loaded web page) come into Express and for that request handler to send data to that particular client over it’s corresponding socket.io connection. Using some sort of cookie client identifier, one can associate an existing socket.io connection with an incoming http request.

I should add that what I’ve described above is how things work when you are making a socket.io connection to the same host and port that the web page was loaded from. This is not required. You could have one http server that all your web pages and web resources are loaded from and another http server (on a different host/port combination) that fields incoming socket.io requests. In that case, the express side of things would really have nothing to do with the socket.io side of things. They would literally be different servers, would probably not share cookies, etc…