UNPKG

@cloudflare/actors

Version:

An easier way to build with Cloudflare Durable Objects

80 lines 3.5 kB
export class Sockets { constructor(ctx, parent) { this.connections = new Map(); this.context = ctx; this.parent = parent; if (ctx) { // When the actor is initialized, we should load any existing websockets // that are currently connected to this actor. const webSockets = ctx.getWebSockets(); this.connections = new Map(); webSockets.forEach((socket) => { // Retrieve the attachment data which contains connectionId and queryParams const attachment = socket.deserializeAttachment?.() || {}; // Use the connection ID from attachment, or generate a new one if not available const connectionId = attachment.connectionId || crypto.randomUUID(); // Store the connection with its ID this.connections.set(connectionId, socket); // If a user wants to get access to additional metadata that was part of the query // params from when they established the connection, they can do so by using the // `deserializeAttachment` method on the socket. // const queryParams = socket.deserializeAttachment?.()?.queryParams || {}; }); } } message(message, to, exclude) { for (const [id, socket] of this.connections.entries()) { // Skip if the `id` or `socket` is in the `exclude` list if (exclude?.includes(id) || exclude?.includes(socket)) { continue; } // Send to all if 'to' is '*' or empty, otherwise only to specified recipients if (to === "*" || !to?.length || to.includes(id) || to.includes(socket)) { socket.send(message); } } } async webSocketMessage(ws, message) { } async webSocketClose(ws, code) { // When a particular user has ended its websocket connection, we should // find their entry in our connections map and prune it from our list we are // managing. for (const [id, socket] of this.connections.entries()) { if (socket === ws) { // Remove from connections map this.connections.delete(id); break; } } ws.close(code, "Durable Object is closing WebSocket"); } acceptWebSocket(request) { const webSocketPair = new WebSocketPair(); const [client, server] = Object.values(webSocketPair); // Parse the URL and get all query parameters const url = new URL(request.url); const params = url.searchParams; // Create an object to store all query parameters const queryParams = {}; params.forEach((value, key) => { queryParams[key] = value; }); // If no ID was provided, generate one const connectionId = queryParams.id || crypto.randomUUID(); if (!queryParams.id) { queryParams.id = connectionId; } // Store all query parameters in the WebSocket's attachment to persist across hibernation if (server.serializeAttachment) { server.serializeAttachment({ connectionId, queryParams }); } this.connections.set(connectionId, server); this.context?.acceptWebSocket(server); return { client, server }; } } //# sourceMappingURL=index.js.map