Skip to content

Commit 02aa935

Browse files
committed
Changing 4-space indentation to 2-space indentation
1 parent 77b7ea8 commit 02aa935

File tree

1 file changed

+117
-117
lines changed

1 file changed

+117
-117
lines changed

src/content/docs/durable-objects/examples/websocket-hibernation-server.mdx

Lines changed: 117 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -28,130 +28,130 @@ import { DurableObject } from 'cloudflare:workers';
2828

2929
// Worker
3030
export default {
31-
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
32-
if (request.url.endsWith('/websocket')) {
33-
// Expect to receive a WebSocket Upgrade request.
34-
// If there is one, accept the request and return a WebSocket Response.
35-
const upgradeHeader = request.headers.get('Upgrade');
36-
if (!upgradeHeader || upgradeHeader !== 'websocket') {
37-
return new Response('Worker expected Upgrade: websocket', {
38-
status: 426,
39-
});
40-
}
41-
42-
if (request.method !== 'GET') {
43-
return new Response('Worker expected GET method', {
44-
status: 400,
45-
});
46-
}
47-
48-
// Since we are hard coding the Durable Object ID by providing the constant name 'foo',
49-
// all requests to this Worker will be sent to the same Durable Object instance.
50-
let id = env.WEBSOCKET_HIBERNATION_SERVER.idFromName('foo');
51-
let stub = env.WEBSOCKET_HIBERNATION_SERVER.get(id);
52-
53-
return stub.fetch(request);
54-
}
55-
56-
return new Response(
57-
`Supported endpoints:
58-
/websocket: Expects a WebSocket upgrade request`,
59-
{
60-
status: 200,
61-
headers: {
62-
'Content-Type': 'text/plain',
63-
},
64-
}
65-
);
66-
},
67-
};
68-
69-
// Durable Object
70-
export class WebSocketHibernationServer extends DurableObject {
71-
// Keeps track of all WebSocket connections
72-
// When the DO hibernates, gets reconstructed in the constructor
73-
sessions: Map<WebSocket, { [key: string]: string }>;
74-
75-
constructor(ctx: DurableObjectState, env: Env) {
76-
super(ctx, env);
77-
this.sessions = new Map();
78-
79-
// As part of constructing the Durable Object,
80-
// we wake up any hibernating WebSockets and
81-
// place them back in the `sessions` map.
82-
83-
// Get all WebSocket connections from the DO
84-
this.ctx.getWebSockets().forEach((ws) => {
85-
let attachment = ws.deserializeAttachment();
86-
if (attachment) {
87-
// If we previously attached state to our WebSocket,
88-
// let's add it to `sessions` map to restore the state of the connection.
89-
this.sessions.set(ws, { ...attachment });
90-
}
31+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
32+
if (request.url.endsWith('/websocket')) {
33+
// Expect to receive a WebSocket Upgrade request.
34+
// If there is one, accept the request and return a WebSocket Response.
35+
const upgradeHeader = request.headers.get('Upgrade');
36+
if (!upgradeHeader || upgradeHeader !== 'websocket') {
37+
return new Response('Worker expected Upgrade: websocket', {
38+
status: 426,
9139
});
40+
}
9241

93-
// Sets an application level auto response that does not wake hibernated WebSockets.
94-
this.ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair('ping', 'pong'));
95-
}
96-
97-
async fetch(request: Request): Promise<Response> {
98-
// Creates two ends of a WebSocket connection.
99-
const webSocketPair = new WebSocketPair();
100-
const [client, server] = Object.values(webSocketPair);
101-
102-
// Calling `acceptWebSocket()` informs the runtime that this WebSocket is to begin terminating
103-
// request within the Durable Object. It has the effect of "accepting" the connection,
104-
// and allowing the WebSocket to send and receive messages.
105-
// Unlike `ws.accept()`, `this.ctx.acceptWebSocket(ws)` informs the Workers Runtime that the WebSocket
106-
// is "hibernatable", so the runtime does not need to pin this Durable Object to memory while
107-
// the connection is open. During periods of inactivity, the Durable Object can be evicted
108-
// from memory, but the WebSocket connection will remain open. If at some later point the
109-
// WebSocket receives a message, the runtime will recreate the Durable Object
110-
// (run the `constructor`) and deliver the message to the appropriate handler.
111-
this.ctx.acceptWebSocket(server);
112-
113-
// Generate a random UUID for the session.
114-
const id = crypto.randomUUID();
115-
116-
// Attach the session ID to the WebSocket connection and serialize it.
117-
// This is necessary to restore the state of the connection when the Durable Object wakes up.
118-
server.serializeAttachment({ id });
119-
120-
// Add the WebSocket connection to the map of active sessions.
121-
this.sessions.set(server, { id });
122-
123-
return new Response(null, {
124-
status: 101,
125-
webSocket: client,
42+
if (request.method !== 'GET') {
43+
return new Response('Worker expected GET method', {
44+
status: 400,
12645
});
127-
}
128-
129-
async webSocketMessage(ws: WebSocket, message: ArrayBuffer | string) {
130-
// Get the session associated with the WebSocket connection.
131-
const session = this.sessions.get(ws)!;
46+
}
13247

133-
// Upon receiving a message from the client, the server replies with the same message, the session ID of the connection,
134-
// and the total number of connections with the "[Durable Object]: " prefix
135-
ws.send(`[Durable Object] message: ${message}, from: ${session.id}. Total connections: ${this.sessions.size}`);
48+
// Since we are hard coding the Durable Object ID by providing the constant name 'foo',
49+
// all requests to this Worker will be sent to the same Durable Object instance.
50+
let id = env.WEBSOCKET_HIBERNATION_SERVER.idFromName('foo');
51+
let stub = env.WEBSOCKET_HIBERNATION_SERVER.get(id);
13652

137-
// Send a message to all WebSocket connections, loop over all the connected WebSockets.
138-
this.sessions.forEach((attachment, session) => {
139-
session.send(`[Durable Object] message: ${message}, from: ${attachment.id}. Total connections: ${this.sessions.size}`);
140-
});
141-
142-
// Send a message to all WebSocket connections except the connection (ws),
143-
// loop over all the connected WebSockets and filter out the connection (ws).
144-
this.sessions.forEach((attachment, session) => {
145-
if (session !== ws) {
146-
session.send(`[Durable Object] message: ${message}, from: ${attachment.id}. Total connections: ${this.sessions.size}`);
147-
}
148-
});
53+
return stub.fetch(request);
14954
}
15055

151-
async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) {
152-
// If the client closes the connection, the runtime will invoke the webSocketClose() handler.
153-
ws.close(code, 'Durable Object is closing WebSocket');
154-
}
56+
return new Response(
57+
`Supported endpoints:
58+
/websocket: Expects a WebSocket upgrade request`,
59+
{
60+
status: 200,
61+
headers: {
62+
'Content-Type': 'text/plain',
63+
},
64+
}
65+
);
66+
},
67+
};
68+
69+
// Durable Object
70+
export class WebSocketHibernationServer extends DurableObject {
71+
// Keeps track of all WebSocket connections
72+
// When the DO hibernates, gets reconstructed in the constructor
73+
sessions: Map<WebSocket, { [key: string]: string }>;
74+
75+
constructor(ctx: DurableObjectState, env: Env) {
76+
super(ctx, env);
77+
this.sessions = new Map();
78+
79+
// As part of constructing the Durable Object,
80+
// we wake up any hibernating WebSockets and
81+
// place them back in the `sessions` map.
82+
83+
// Get all WebSocket connections from the DO
84+
this.ctx.getWebSockets().forEach((ws) => {
85+
let attachment = ws.deserializeAttachment();
86+
if (attachment) {
87+
// If we previously attached state to our WebSocket,
88+
// let's add it to `sessions` map to restore the state of the connection.
89+
this.sessions.set(ws, { ...attachment });
90+
}
91+
});
92+
93+
// Sets an application level auto response that does not wake hibernated WebSockets.
94+
this.ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair('ping', 'pong'));
95+
}
96+
97+
async fetch(request: Request): Promise<Response> {
98+
// Creates two ends of a WebSocket connection.
99+
const webSocketPair = new WebSocketPair();
100+
const [client, server] = Object.values(webSocketPair);
101+
102+
// Calling `acceptWebSocket()` informs the runtime that this WebSocket is to begin terminating
103+
// request within the Durable Object. It has the effect of "accepting" the connection,
104+
// and allowing the WebSocket to send and receive messages.
105+
// Unlike `ws.accept()`, `this.ctx.acceptWebSocket(ws)` informs the Workers Runtime that the WebSocket
106+
// is "hibernatable", so the runtime does not need to pin this Durable Object to memory while
107+
// the connection is open. During periods of inactivity, the Durable Object can be evicted
108+
// from memory, but the WebSocket connection will remain open. If at some later point the
109+
// WebSocket receives a message, the runtime will recreate the Durable Object
110+
// (run the `constructor`) and deliver the message to the appropriate handler.
111+
this.ctx.acceptWebSocket(server);
112+
113+
// Generate a random UUID for the session.
114+
const id = crypto.randomUUID();
115+
116+
// Attach the session ID to the WebSocket connection and serialize it.
117+
// This is necessary to restore the state of the connection when the Durable Object wakes up.
118+
server.serializeAttachment({ id });
119+
120+
// Add the WebSocket connection to the map of active sessions.
121+
this.sessions.set(server, { id });
122+
123+
return new Response(null, {
124+
status: 101,
125+
webSocket: client,
126+
});
127+
}
128+
129+
async webSocketMessage(ws: WebSocket, message: ArrayBuffer | string) {
130+
// Get the session associated with the WebSocket connection.
131+
const session = this.sessions.get(ws)!;
132+
133+
// Upon receiving a message from the client, the server replies with the same message, the session ID of the connection,
134+
// and the total number of connections with the "[Durable Object]: " prefix
135+
ws.send(`[Durable Object] message: ${message}, from: ${session.id}. Total connections: ${this.sessions.size}`);
136+
137+
// Send a message to all WebSocket connections, loop over all the connected WebSockets.
138+
this.sessions.forEach((attachment, session) => {
139+
session.send(`[Durable Object] message: ${message}, from: ${attachment.id}. Total connections: ${this.sessions.size}`);
140+
});
141+
142+
// Send a message to all WebSocket connections except the connection (ws),
143+
// loop over all the connected WebSockets and filter out the connection (ws).
144+
this.sessions.forEach((attachment, session) => {
145+
if (session !== ws) {
146+
session.send(`[Durable Object] message: ${message}, from: ${attachment.id}. Total connections: ${this.sessions.size}`);
147+
}
148+
});
149+
}
150+
151+
async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) {
152+
// If the client closes the connection, the runtime will invoke the webSocketClose() handler.
153+
ws.close(code, 'Durable Object is closing WebSocket');
154+
}
155155
}
156156
```
157157
</TypeScriptExample>

0 commit comments

Comments
 (0)