mirror of
https://github.com/tiennm99/rplace.git
synced 2026-09-03 10:23:50 +00:00
fix: use Hibernation API for reliable WebSocket broadcast
Replace manual session tracking with Cloudflare's Hibernation API so WebSocket connections survive Durable Object eviction.
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
/**
|
||||
* Durable Object for WebSocket broadcast room.
|
||||
* All connected clients receive pixel updates in real-time.
|
||||
* Uses Hibernation API so connections survive DO eviction.
|
||||
*/
|
||||
export class CanvasRoom {
|
||||
constructor(state) {
|
||||
this.state = state;
|
||||
/** @type {Set<WebSocket>} */
|
||||
this.sessions = new Set();
|
||||
}
|
||||
|
||||
async fetch(request) {
|
||||
@@ -16,11 +14,11 @@ export class CanvasRoom {
|
||||
if (url.pathname === '/broadcast' && request.method === 'POST') {
|
||||
const pixels = await request.json();
|
||||
const message = JSON.stringify({ type: 'pixels', pixels });
|
||||
for (const ws of this.sessions) {
|
||||
for (const ws of this.state.getWebSockets()) {
|
||||
try {
|
||||
ws.send(message);
|
||||
} catch {
|
||||
this.sessions.delete(ws);
|
||||
ws.close(1011, 'send failed');
|
||||
}
|
||||
}
|
||||
return new Response('ok');
|
||||
@@ -30,17 +28,23 @@ export class CanvasRoom {
|
||||
const pair = new WebSocketPair();
|
||||
const [client, server] = Object.values(pair);
|
||||
|
||||
server.accept();
|
||||
this.sessions.add(server);
|
||||
|
||||
server.addEventListener('close', () => {
|
||||
this.sessions.delete(server);
|
||||
});
|
||||
|
||||
server.addEventListener('error', () => {
|
||||
this.sessions.delete(server);
|
||||
});
|
||||
this.state.acceptWebSocket(server);
|
||||
|
||||
return new Response(null, { status: 101, webSocket: client });
|
||||
}
|
||||
|
||||
/** Called when a WebSocket receives a message (required by Hibernation API) */
|
||||
webSocketMessage(ws, message) {
|
||||
// Clients don't send messages in this protocol; ignore.
|
||||
}
|
||||
|
||||
/** Called when a WebSocket is closed */
|
||||
webSocketClose(ws, code, reason, wasClean) {
|
||||
ws.close(code, reason);
|
||||
}
|
||||
|
||||
/** Called on WebSocket error */
|
||||
webSocketError(ws, error) {
|
||||
ws.close(1011, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user