When extending the DurableObject class
import { Environment } from "@/src/types";
import { DurableObject } from "cloudflare:workers";
interface Client {
websocket: WebSocket;
id: string;
}
export class WebSocketHibernationServer extends DurableObject {
clients: Map<string, Client>;
constructor(ctx: DurableObjectState, env: Environment) {
super(ctx, env);
this.clients = new Map();
}
async fetch(request: Request): Promise<Response> {
let pair = new WebSocketPair();
const [client, server] = Object.values(pair);
this.ctx.acceptWebSocket(server);
await this.handleWebSocketSession(server);
return new Response(null, { status: 101, webSocket: client });
}
async handleWebSocketSession(webSocket: WebSocket) {
const clientId = crypto.randomUUID();
this.clients.set(clientId, {
id: clientId,
websocket: webSocket,
});
}
async webSocketMessage(ws: WebSocket, message: ArrayBuffer | string) {
this.broadcast(
`[Durable Object] message: ${message}, connections: ${this.ctx.getWebSockets().length}`
);
}
async webSocketClose(ws: WebSocket, code: number, reason: string) {
ws.close(code, reason);
}
broadcast(message: string) {
this.clients.forEach((client, key) => {
try {
client.websocket.send(message);
} catch (err) {
this.clients.delete(key);
}
});
}