Cloudflare Workers

pluv.io supports building real-time APIs with Cloudflare Workers through their Durable Objects API.

Using with Cloudflare Workers

Let's step through how we'd put together a real-time API for Cloudflare Workers. The examples below assumes a basic understanding of Cloudflare Workers and Durable Objects.

Install dependencies

1# For the server
2npm install @pluv/io @pluv/platform-cloudflare
3# Server peer-dependencies
4npm install yjs zod

Create PluvIO instance

Define an io (websocket client) instance on the server codebase:

1// backend/io.ts
2
3import { createIO } from "@pluv/io";
4import { platformCloudflare } from "@pluv/platform-cloudflare";
5
6export const io = createIO({ platform: platformCloudflare() });
7
8// Export the websocket client io type, instead of the client itself
9export type AppPluvIO = typeof io;

Attach to a RoomDurableObject

Next, create a RoomDurableObject and attach our new pluv.io instance to the room:

1// server/RoomDurableObject.ts
2
3import { type InferIORoom } from "@pluv/io";
4import { AppPluvIO, io } from "./io";
5
6export class RoomDurableObject implements DurableObject {
7 private _io: InferIORoom<AppPluvIO>;
8
9 constructor(state: DurableObjectState) {
10 this._io = io.getRoom(state.id.toString());
11 }
12
13 async fetch(request: Request) {
14 const isWebSocketRequest = request.headers.get("Upgrade") === "WebSocket";
15
16 if (!isWebSocketRequest) {
17 return new Response("Expected WebSocket", { status: 400 });
18 }
19
20 const { 0: client, 1: server } = new WebSocketPair();
21
22 await this._io.register(server);
23
24 return new Response(null, { status: 101, webSocket: client });
25 }
26}

Forward request to RoomDurableObject

Lastly, integrate your RoomDurableObject with your Cloudflare Worker's default handler:

1// server/index.ts
2
3const parseRoomId = (url: string): string => {
4 /* get room from req.url */
5};
6
7const handler = {
8 async fetch(req: Request, env: Env): Promise<Response> {
9 const roomId = parseRoomId(req.url);
10 const durableObjectId = env.rooms.idFromString(roomId);
11
12 const room = env.rooms.get(durableObjectId);
13
14 return room.fetch(request);
15 },
16};
17
18export default handler;

From this point on, you can integrate your frontend with @pluv/react as you would normally.