Brendan McKenzie

Multiple WebSocket servers in a single Express instance

Saturday, 28 August 2021

I use Postgraphile for a lot of things. It gives me an extremely powerful GraphQL interface to my PostgreSQL databases. It also supports pub/sub subscriptions for realtime data updates.

As part of an application I was building I needed another WebSocket server for other client interactions that didn’t touch the database, so the WebSocket implementation in Postgraphile couldn’t do what I wanted.

A lot of articles describing how to setup a WebSocket server with Express tell you to hook into the upgrade event of the Express server.

Since I didn’t want to interfere with the subscription functionality of Postgraphile this wouldn’t cut it.

Thankfully, Postgraphile only listens to upgrade events that are sent to /graphql (by default, this route is configurable).

Using the same approach I could configure my WebSocket server to listen on my own route.

1const wsServer = new ws.Server({ noServer: true });
2
3const app = express();
4
5const server = app.listen(3000);
6
7server.on("upgrade", (request, socket, head) => {
8  if (request.url === "/custom") {
9    wsServer.handleUpgrade(request, socket, head, (client) => {
10      wsServer.emit("connection", client, request);
11    });
12  }
13});