new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Runtime · all subjects

websockets

22 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

WebSocket chat server benchmark structure

The websocket-server benchmark implements a simple but very active chat room. The server waits for 32 clients by default. When a client sends a message like 'foo', the server broadcasts back 'John: foo' so all chatroom members receive it. The client script loops through a list of messages for each connected client and waits until it receives all messages for each client before sending the next batch.

Running WebSocket client in Bun, Node, or Deno

The WebSocket client script can run in Bun, Node, or Deno. Execute with: node ./chat-client.mjs

WebSocket benchmark default client count

The websocket-server benchmark uses 32 clients by default, which the client script handles.

WebSocket perMessageDeflate compression parameter

Set the `perMessageDeflate` parameter to `true` in the websocket configuration passed to Bun.serve() to enable compression for all WebSocket messages using the permessage-deflate WebSocket extension as defined in RFC 7692.

ws.send() compression parameter

Pass `true` as the second parameter to `ws.send()` to enable compression for an individual WebSocket message.

WebSocket compression example with perMessageDeflate

Bun.serve({ websocket: { perMessageDeflate: true, }, });

WebSocket compression example per message

Bun.serve({ websocket: { async message(ws, message) { ws.send(message, true); }, }, });

server.upgrade() data parameter for WebSocket context

When upgrading a connection to WebSocket in Bun.serve(), pass a `data` parameter to server.upgrade(req, { data: {...} }) to attach contextual data to each socket. This data is stored per-socket and can be accessed as the `data` property on the WebSocket instance in all WebSocket handlers.

WebSocket contextual data access in handlers

In WebSocket handlers like message(), the contextual data passed during upgrade is accessible via ws.data. For example, if data: { socketId: 123 } was passed during upgrade, ws.data.socketId will be 123 in the handler.

TypeScript typing for WebSocket data

To specify the type of WebSocket contextual data in TypeScript, add a `data` property to the websocket configuration object with a type annotation. For example: `websocket: { data: {} as { socketId: number }, ... }` defines that ws.data will have a socketId property of type number.

WebSocket contextual data pattern with cookies and headers

A common pattern is to extract cookies or headers from the incoming request during upgrade to identify the client, then pass this information as contextual data to server.upgrade(). This allows storing identifying information like user ID, token, or creation timestamp for use in WebSocket handlers.

WebSocket upgrade example with contextual data

Example showing contextual data usage: ```ts Bun.serve({ fetch(req, server) { const success = server.upgrade(req, { data: { socketId: Math.random(), }, }); if (success) return undefined; }, websocket: { data: {} as { socketId: number }, async message(ws, message) { console.log(`Received ${message} from ${ws.data.socketId}`); }, }, }); ```

WebSocket contextual data with authentication example

Example showing contextual data with token and user information: ```ts type WebSocketData = { createdAt: number; token: string; userId: string; }; Bun.serve({ async fetch(req, server) { const cookies = parseCookies(req.headers.get("Cookie")); const token = cookies["X-Token"]; const user = await getUserFromToken(token); const upgraded = server.upgrade(req, { data: { createdAt: Date.now(), token: cookies["X-Token"], userId: user.id, }, }); if (upgraded) return undefined; }, websocket: { data: {} as WebSocketData, async message(ws, message) { await saveMessageToDatabase({ message: String(message), userId: ws.data.userId, }); }, }, }); ```

WebSocket pub-sub subscribe method

Subscribe a socket to a named channel using socket.subscribe(<name>). This allows the socket to receive published messages sent to that channel.

WebSocket pub-sub publish method

Publish a message to a channel using socket.publish(<name>, <message>). This sends the message to all sockets subscribed to that channel. Can also use server.publish(<name>, <message>) to publish from the server.

WebSocket unsubscribe method

Unsubscribe a socket from a named channel using ws.unsubscribe(<name>). This stops the socket from receiving messages published to that channel.

WebSocket open handler lifecycle

The open(ws) handler is called when a WebSocket connection is established. It receives the WebSocket instance and can access ws.data, ws.subscribe(), and publish messages.

WebSocket message handler lifecycle

The message(ws, message) handler is called when the server receives a message from a connected WebSocket. It receives the WebSocket instance and the message data.

WebSocket close handler lifecycle

The close(ws) handler is called when a WebSocket connection closes. It receives the WebSocket instance and can perform cleanup like unsubscribing from channels.

WebSocket data property typing in TypeScript

In Bun.serve() websocket config, specify the type of ws.data using the data property with an as type annotation: data: {} as { username: string }. This allows TypeScript to properly type the data object passed via server.upgrade().

WebSocket upgrade in Bun.serve fetch handler

Call server.upgrade(req, { data: { /* custom data */ } }) in the fetch handler to upgrade an HTTP request to a WebSocket connection. The data property can be used to attach custom metadata to the WebSocket. Returns true on success, false otherwise.

Basic WebSocket server example pattern in Bun

Example of a basic pub-sub WebSocket chat server: const server = Bun.serve({ fetch(req, server) { const cookies = req.headers.get("cookie"); const username = getUsernameFromCookies(cookies); const success = server.upgrade(req, { data: { username } }); if (success) return undefined; return new Response("Hello world"); }, websocket: { data: {} as { username: string }, open(ws) { const msg = `${ws.data.username} has entered the chat`; ws.subscribe("the-group-chat"); server.publish("the-group-chat", msg); }, message(ws, message) { server.publish("the-group-chat", `${ws.data.username}: ${message}`); }, close(ws) { const msg = `${ws.data.username} has left the chat`; server.publish("the-group-chat", msg); ws.unsubscribe("the-group-chat"); }, }, }); console.log(`Listening on ${server.hostname}:${server.port}`);

Give your agent this brain