Build a WebSocket server with origin checks, authentication hooks, heartbeat detection, message-size limits, broadcast backpressure awareness, and predictable disconnect cleanup.
What you will build
This tutorial produces a working, verifiable result rather than a command list. Read each command before running it, keep configuration in version control without secrets, and record the versions used for repeatable deployment.
1. Prepare the project
mkdir websocket-demo && cd websocket-demo
npm init -y
npm pkg set type=module
npm install ws
Run preparation commands as an unprivileged application user unless a command explicitly requires sudo. A clean working tree and lockfile make rollback much easier.
2. Implement the solution
import { WebSocketServer, WebSocket } from 'ws';
const wss=new WebSocketServer({port:8080,maxPayload:64*1024});
wss.on('connection',(socket,request)=>{
if(request.headers.origin!=='https://example.com') return socket.close(1008,'origin denied');
socket.alive=true; socket.on('pong',()=>socket.alive=true);
socket.on('message',data=>{for(const client of wss.clients) if(client.readyState===WebSocket.OPEN && client.bufferedAmount<1_000_000) client.send(data);});
});
const timer=setInterval(()=>{for(const socket of wss.clients){if(!socket.alive){socket.terminate();continue;} socket.alive=false;socket.ping();}},30_000);
wss.on('close',()=>clearInterval(timer));
Save the example in the filename indicated by its comment or surrounding instructions. Treat it as a minimal baseline: production applications should separate transport, business logic, persistence, and configuration into testable modules.
3. Verify end to end
node server.js
npx wscat -H 'Origin: https://example.com' -c ws://127.0.0.1:8080
ss -ltnp | grep 8080
Verification should cover both process state and a real request or data operation. A process that is merely running is not necessarily ready to serve traffic.
4. Troubleshooting and production notes
Authenticate during the HTTP upgrade or immediately after connection with a strict deadline. Use TLS in production, enforce message schemas, cap payload size, and plan cross-replica fan-out through a broker such as Redis rather than assuming every client shares one process.
Production checklist
- The supported Node.js LTS version and dependency lockfile are recorded.
- Configuration is validated at startup and secrets are stored outside source control.
- Input limits, authentication, authorization, timeouts, and error boundaries are explicit.
- Logs identify a request without exposing credentials or personal data.
- Health checks, graceful termination, resource limits, backup, and rollback have been tested.
Reference: official topic documentation. For production version selection, use a supported LTS line from the Node.js release schedule.