aboutsummaryrefslogtreecommitdiff
path: root/docs/api/websockets.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/api/websockets.md')
-rw-r--r--docs/api/websockets.md51
1 files changed, 35 insertions, 16 deletions
diff --git a/docs/api/websockets.md b/docs/api/websockets.md
index 0c40a05c0..d1e1d3831 100644
--- a/docs/api/websockets.md
+++ b/docs/api/websockets.md
@@ -20,7 +20,7 @@ To connect to an external socket server, create an instance of `WebSocket` with
const socket = new WebSocket("ws://localhost:3000");
```
-Bun supports setting custom headers. This is a Bun-specific extension of the `WebSocket` standard.
+Bun supports setting custom headers. This is a Bun-specific extension of the `WebSocket` standard. _This will not work in browsers._
```ts
const socket = new WebSocket("ws://localhost:3000", {
@@ -150,11 +150,13 @@ type WebSocketData = {
// TypeScript: specify the type of `data`
Bun.serve<WebSocketData>({
fetch(req, server) {
+ const cookies = parseCookies(req.headers.get("Cookie"));
server.upgrade(req, {
// TS: this object must conform to WebSocketData
data: {
createdAt: Date.now(),
channelId: new URL(req.url).searchParams.get("channelId"),
+ authToken: cookies["X-Token"],
},
});
@@ -173,42 +175,59 @@ Bun.serve<WebSocketData>({
});
```
+To connect to this server from the browser, create a new `WebSocket`.
+
+```ts#browser.js
+const socket = new WebSocket("ws://localhost:3000/chat");
+
+socket.addEventListener("message", event => {
+ console.log(event.data);
+})
+```
+
+The cookies that are currently set on the page will be sent with the WebSocket upgrade request and available on `req.headers` in the `fetch` handler. Parse these cookies to determine the identity of the connecting user and set the value of `data` accordingly.
+
## Pub/Sub
Bun's `ServerWebSocket` implementation implements a native publish-subscribe API for topic-based broadcasting. Individual sockets can `.subscribe()` to a topic (specified with a string identifier) and `.publish()` messages to all other subscribers to that topic. This topic-based broadcast API is similar to [MQTT](https://en.wikipedia.org/wiki/MQTT) and [Redis Pub/Sub](https://redis.io/topics/pubsub).
```ts
-const pubsubserver = Bun.serve<{username: string}>({
+const server = Bun.serve<{ username: string }>({
fetch(req, server) {
- if (req.url === '/chat') {
- const cookies = getCookieFromRequest(req);
- const success = server.upgrade(req, {
- data: {username: cookies.username},
- });
- return success
- ? undefined
- : new Response('WebSocket upgrade error', {status: 400});
+ const url = new URL(req.url);
+ if (url.pathname === "/chat") {
+ console.log(`upgrade!`);
+ const username = getUsernameFromReq(req);
+ const success = server.upgrade(req, { data: { username } });
+ return success ? undefined : new Response("WebSocket upgrade error", { status: 400 });
}
- return new Response('Hello world');
+ return new Response("Hello world");
},
websocket: {
open(ws) {
- ws.subscribe('the-group-chat');
- ws.publish('the-group-chat', `${ws.data.username} has entered the chat`);
+ const msg = `${ws.data.username} has entered the chat`;
+ ws.subscribe("the-group-chat");
+ ws.publish("the-group-chat", msg);
},
message(ws, message) {
// this is a group chat
// so the server re-broadcasts incoming message to everyone
- ws.publish('the-group-chat', `${ws.data.username}: ${message}`);
+ ws.publish("the-group-chat", `${ws.data.username}: ${message}`);
},
close(ws) {
- ws.unsubscribe('the-group-chat');
- ws.publish('the-group-chat', `${ws.data.username} has left the chat`);
+ const msg = `${ws.data.username} has left the chat`;
+ ws.unsubscribe("the-group-chat");
+ ws.publish("the-group-chat", msg);
},
+ },
});
+
+console.log(`Listening on ${server.hostname}:${server.port}`);
```
+Calling `.publish(data)` will send the message to all subscribers of a topic (excluding the socket that called `.publish()`).
+
## Compression
Per-message [compression](https://websockets.readthedocs.io/en/stable/topics/compression.html) can be enabled with the `perMessageDeflate` parameter.