From 513aa0a3169fc73fb2a5141c4172e926469538e2 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sat, 11 Apr 2026 16:58:31 +0200 Subject: [PATCH] fix: use fetch() instead of RPC for DO WebSocket upgrades DO RPC doesn't support WebSocket upgrade requests. Forward the request via stub.fetch() and pass userId/channelId via custom headers. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/chat-worker/src/durable-objects/ChatRoom.ts | 13 ++++++++++++- apps/chat-worker/src/index.ts | 9 ++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/chat-worker/src/durable-objects/ChatRoom.ts b/apps/chat-worker/src/durable-objects/ChatRoom.ts index 8c1982c..95e4e7f 100644 --- a/apps/chat-worker/src/durable-objects/ChatRoom.ts +++ b/apps/chat-worker/src/durable-objects/ChatRoom.ts @@ -12,7 +12,18 @@ export class ChatRoom extends DurableObject { return this.postgrest; } - async handleWebSocket(request: Request, userId: string, channelId: string): Promise { + /** + * Handle incoming fetch requests — WebSocket upgrades are forwarded here by the Worker. + * userId and channelId are passed via custom headers set by the Worker. + */ + async fetch(request: Request): Promise { + const userId = request.headers.get("X-User-Id"); + const channelId = request.headers.get("X-Channel-Id"); + + if (!userId || !channelId) { + return new Response("Missing user or channel identity", { status: 400 }); + } + const pair = new WebSocketPair(); const [client, server] = [pair[0], pair[1]]; diff --git a/apps/chat-worker/src/index.ts b/apps/chat-worker/src/index.ts index ec03c56..5eb2a65 100644 --- a/apps/chat-worker/src/index.ts +++ b/apps/chat-worker/src/index.ts @@ -70,7 +70,14 @@ app.get("/chat/ws/:channelId", async (c) => { const id = c.env.CHAT_ROOM.idFromName(channelId); const stub = c.env.CHAT_ROOM.get(id); - return (stub as any).handleWebSocket(c.req.raw, userId, channelId); + + // Forward the WebSocket upgrade via fetch — DO RPC doesn't support WebSocket upgrades. + // Pass userId and channelId via headers so the DO can read them. + const url = new URL(c.req.url); + const doRequest = new Request(url.toString(), c.req.raw); + doRequest.headers.set("X-User-Id", userId); + doRequest.headers.set("X-Channel-Id", channelId); + return stub.fetch(doRequest); }); // GET message history — paginated