Websocket Server in Node.js
Websockets are a tool for bidirectional communication between a browser client and a server. What makes websockets special is that they enable the server to push data to the client.
Here's how you can start a websocket server in Node.js.
Using ws
The ws
npm package is the de facto WebSocket library for Node.js. The ws package also includes a websocket client, which is
useful for testing.
Below is a basic example of a WebSocket server that tracks all open sockets and sends inbound messages to all open sockets. You can think of this as a simple chat server: when one person sends a message, the server broadcasts the message to everyone listening.
const WebSocket = require('ws');
const server = new WebSocket.Server({
port: 8080
});
let sockets = [];
server.on('connection', function(socket) {
sockets.push(socket);
// When you receive a message, send that message to every socket.
socket.on('message', function(msg) {
sockets.forEach(s => s.send(msg));
});
// When a socket closes, or disconnects, remove it from the array.
socket.on('close', function() {
sockets = sockets.filter(s => s !== socket);
});
});
Using ws and Express
The above ws server has to have its own port: it can't listen on the same port as an Express server. However, you can handle websockets from Express using ws by listening to the Express HTTP server's 'upgrade' event as described in 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);
});
});