Koa WebSocket Middleware
raw JSON →koa-websocket is a lightweight wrapper designed to integrate WebSocket functionality into Koa applications, providing a middleware handler that is compatible with `koa-route`. It leverages the popular `ws` library for its core WebSocket implementation. The package is currently at version 7.0.0 and has seen regular updates, including dependency upgrades to address security concerns and support newer Node.js versions. Key features include support for both `ws://` and `wss://` protocols, the ability to pass custom WebSocket server options, and seamless integration with Koa's middleware pattern via `app.ws.use`. It differentiates itself by offering a `koa-route`-like approach to WebSocket routing within the Koa ecosystem, simplifying the handling of WebSocket connections and messages alongside traditional HTTP routes, providing a structured way to build WebSocket-enabled Koa applications.
Common errors
error TypeError: app.ws.use is not a function ↓
const app = websockify(new Koa()); error Error: Cannot find module 'koa' ↓
npm install koa. error WebSocket connection to 'ws://localhost:3000/some-path' failed: Error during WebSocket handshake: Unexpected response code: 404 ↓
app.ws.use(route.all('/your-path', ...)) handler defined in your server-side code. Check for typos in paths and ensure the handler is correctly registered. error Error: self-signed certificate in certificate chain (for wss:// connections) ↓
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'). Warnings
breaking Version 7.0.0 upgraded the underlying `ws` library to version 8.5.0. This may introduce breaking changes or behavioral shifts from `ws` that could affect your existing WebSocket client or server logic. Always consult the `websockets/ws` release notes. ↓
breaking With `koa-websocket` v6.0.0, the `ws` dependency was upgraded to 7.0.1, which dropped support for Node.js 6.x. Running on older Node.js versions will lead to errors. ↓
breaking `koa-websocket` versions 4.0.0 and above are built for Koa v2. If you are using Koa v1, you must explicitly install `koa-websocket@2` to maintain compatibility. ↓
gotcha WebSocket middleware must be registered using `app.ws.use(...)` and not `app.use(...)`. The `app.use` method is for standard HTTP middleware, while `app.ws.use` is specific to WebSocket connections. ↓
gotcha Within `app.ws.use` middleware or route handlers, the Koa context (`ctx`) is augmented with the active WebSocket connection at `ctx.websocket`. You must use `ctx.websocket` to interact with the client. ↓
gotcha To enable `wss://` (secure WebSockets), you must provide `httpsOptions` as the third argument to the `websockify` function. Without these options, only `ws://` connections will be supported. ↓
Install
npm install koa-websocket yarn add koa-websocket pnpm add koa-websocket Imports
- websockify wrong
import { websockify } from 'koa-websocket'; // This is not a named export. const websockify = require('koa-websocket'); // Functional CommonJS syntax, but ESM is preferred in modern Koa projects.correctimport websockify from 'koa-websocket'; - Koa wrong
const Koa = require('koa');correctimport Koa from 'koa'; - route wrong
const route = require('koa-route');correctimport route from 'koa-route';
Quickstart
import Koa from 'koa';
import route from 'koa-route';
import websockify from 'koa-websocket';
// Create a new Koa application and extend it with WebSocket capabilities
const app = websockify(new Koa());
// Basic HTTP middleware (optional, but shows coexistence)
app.use(async (ctx, next) => {
console.log(`HTTP Request: ${ctx.method} ${ctx.path}`);
await next();
});
// Global WebSocket middleware for all connections
app.ws.use(async (ctx, next) => {
console.log(`New WebSocket connection established for path: ${ctx.path}`);
// You can perform authentication or other setup here
await next(ctx); // Pass context to the next WebSocket middleware or route
});
// WebSocket route handler using koa-route
app.ws.use(route.all('/chat/:id', (ctx) => {
const roomId = ctx.params.id;
console.log(`Client connected to chat room: ${roomId}`);
// Send a welcome message to the newly connected client
ctx.websocket.send(`Welcome to chat room ${roomId}!`);
// Listen for messages from this client
ctx.websocket.on('message', (message) => {
console.log(`Message from client in room ${roomId}: ${message}`);
// Echo the message back to the sender
ctx.websocket.send(`Echo (${roomId}): ${message}`);
});
// Handle client disconnection
ctx.websocket.on('close', () => {
console.log(`Client disconnected from chat room: ${roomId}`);
});
// Handle WebSocket errors
ctx.websocket.on('error', (err) => {
console.error(`WebSocket error in room ${roomId}:`, err.message);
});
}));
// Start the server on an available port, defaulting to 3000
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server listening on http://localhost:${PORT} and ws://localhost:${PORT}`);
console.log('Try connecting with a WebSocket client to ws://localhost:3000/chat/general');
});