Koa WebSocket Middleware

raw JSON →
7.0.0 verified Thu Apr 23 auth: no javascript

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.

error TypeError: app.ws.use is not a function
cause The Koa application instance was not correctly wrapped by the `websockify` function from `koa-websocket`.
fix
Ensure your Koa app is initialized by wrapping it: const app = websockify(new Koa());
error Error: Cannot find module 'koa'
cause The `koa` package, which is a peer dependency in practice, has not been installed in your project.
fix
Install Koa: npm install koa.
error WebSocket connection to 'ws://localhost:3000/some-path' failed: Error during WebSocket handshake: Unexpected response code: 404
cause The WebSocket client is trying to connect to a path for which no `app.ws.use` route handler is configured or the path is incorrect.
fix
Verify that your client's WebSocket URL matches an 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)
cause When using `wss://` with a self-signed or otherwise untrusted SSL certificate, clients will typically reject the connection unless explicitly configured to trust the certificate.
fix
For production, use a trusted SSL certificate from a Certificate Authority (e.g., Let's Encrypt). For development, configure your client to ignore self-signed certificates if applicable (e.g., for Node.js clients, process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0').
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.
fix Review the official `websockets/ws` GitHub releases for version 8.x for specific breaking changes. Thoroughly test your application, including client-side WebSocket interactions, after upgrading `koa-websocket`.
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.
fix Upgrade your Node.js runtime environment to version 8.x or newer. For current releases of `koa-websocket`, Node.js 12+ is generally recommended.
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.
fix For Koa v1 projects, install `npm install koa-websocket@2`. For Koa v2 and newer, use `npm install koa-websocket` to get the latest compatible version.
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.
fix Ensure all functions intended to handle WebSocket connections or messages are passed to `app.ws.use`.
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.
fix To send data, use `ctx.websocket.send()`. To listen for client messages or connection events, use `ctx.websocket.on('message', ...)` or `ctx.websocket.on('close', ...)`, etc.
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.
fix Pass a valid `httpsOptions` object (containing `key`, `cert`, etc.) from your SSL certificate setup as `websockify(new Koa(), wsOptions, httpsOptions)`.
npm install koa-websocket
yarn add koa-websocket
pnpm add koa-websocket

This quickstart demonstrates setting up a Koa application that handles both HTTP and WebSocket requests using `koa-websocket` and `koa-route`. It includes global WebSocket middleware and a specific route for `/chat/:id` to manage and interact with client messages.

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');
});