Handling Websockets with Express

Mar 9, 2020

The ws npm module is the de facto library for websockets in Node.js. It has built-in support for Node.js' native http servers. But, unfortunately, very few developers use Node's built-in HTTP package directly, they usually use Express.

Integrating the ws package with Express is easy. There is also an express-ws module on npm, but I've never managed to get that module to work. Here's how you can use the ws package to listen to websockets on an Express server.

Listening to Websockets with Express

The ws package supports native Node.js HTTP servers. Conveniently, Express' listen() function returns a native Node.js HTTP server. So you can use the same process described in the ws docs:

const express = require('express');
const ws = require('ws');

const app = express();

// Set up a headless websocket server that prints any
// events that come in.
const wsServer = new ws.Server({ noServer: true });
wsServer.on('connection', socket => {
  socket.on('message', message => console.log(message));
});

// `server` is a vanilla Node.js HTTP server, so use
// the same ws upgrade process described here:
// https://www.npmjs.com/package/ws#multiple-servers-sharing-a-single-https-server
const server = app.listen(3000);
server.on('upgrade', (request, socket, head) => {
  wsServer.handleUpgrade(request, socket, head, socket => {
    wsServer.emit('connection', socket, request);
  });
});

Testing

How do you actually connect to this server? ws also has a websocket client implementation as well as the server implementation.

const ws = require('ws');

const client = new ws('ws://localhost:3000');

client.on('open', () => {
  // Causes the server to print "Hello"
  client.send('Hello');
});

More Express Tutorials