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) <noreply@anthropic.com>
This commit is contained in:
Arthur Belleville 2026-04-11 16:58:31 +02:00
parent 28adda9710
commit 513aa0a316
2 changed files with 20 additions and 2 deletions

View file

@ -12,7 +12,18 @@ export class ChatRoom extends DurableObject<Env> {
return this.postgrest;
}
async handleWebSocket(request: Request, userId: string, channelId: string): Promise<Response> {
/**
* 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<Response> {
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]];

View file

@ -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