You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/docs/durable-objects/best-practices/websockets.mdx
+37-50Lines changed: 37 additions & 50 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,30 +11,42 @@ This guide covers how to use Durable Objects as WebSocket servers that can conne
11
11
12
12
There are two sets of WebSockets API:
13
13
14
-
1. Native Durable Object WebSocket API, which allows your Durable Object to hibernate without disconnecting clients when not actively doing work **(recommended)**.
15
-
2. Web Standard WebSocket APIs, using the familiar `addEventListener` event pattern.
14
+
1.**Native Durable Object WebSocket API**, which allows your Durable Object to hibernate without disconnecting clients when not actively doing work **(recommended)**.
15
+
2.**Web Standard WebSocket APIs**, using the familiar `addEventListener` event pattern.
16
16
17
-
###What are WebSockets?
17
+
## What are WebSockets?
18
18
19
19
WebSockets are long-lived TCP connections that enable bi-directional, real-time communication between client and server. Both Cloudflare Durable Objects and Workers can act as WebSocket endpoints – either as a client or as a server. Because WebSocket sessions are long-lived, applications commonly use Durable Objects to accept either the client or server connection. While there are other use cases for using Workers exclusively with WebSockets, for example proxying WebSocket messages, WebSockets are most useful when combined with Durable Objects.
20
20
21
21
Because Durable Objects provide a single-point-of-coordination between [Cloudflare Workers](/workers/), a single Durable Object instance can be used in parallel with WebSockets to coordinate between multiple clients, such as participants in a chat room or a multiplayer game. Refer to [Cloudflare Edge Chat Demo](https://github.com/cloudflare/workers-chat-demo) for an example of using Durable Objects with WebSockets.
22
22
23
23
Both Cloudflare Durable Objects and Workers can use the [Web Standard WebSocket API](/workers/runtime-apis/websockets/) to build applications, but a major differentiator of Cloudflare Durable Objects relative to other platforms is the ability to Hibernate WebSocket connections to save costs. Clients can remain connected when the Durable Object is idle (and not sending messages or running compute tasks), which allows you to push events to clients and minimize the active duration (GB-seconds) associated with long-running Durable Object processes.
24
24
25
-
### WebSocket Hibernation API
25
+
##Durable Objects' Hibernation WebSocket API
26
26
27
-
In addition to [Workers WebSocket API](/workers/runtime-apis/websockets/), Cloudflare Durable Objects can use the WebSocket Hibernation API which extends the Web Standard WebSocket API to reduce costs. Specifically, [billable Duration (GB-s) charges](/durable-objects/platform/pricing/) are not incurred during periods of inactivity. Note that other events, for example [alarms](/durable-objects/api/alarms/), can prevent a Durable Object from being inactive and therefore prevent this cost saving.
27
+
In addition to [the Web Standard WebSocket API](/workers/runtime-apis/websockets/), Cloudflare Durable Objects can use the WebSocket Hibernation API which extends the Web Standard WebSocket API to reduce costs. Specifically, [billable Duration (GB-s) charges](/durable-objects/platform/pricing/) are not incurred during periods of inactivity.
28
28
29
-
The WebSocket consists of Cloudflare-specific extensions to the Web Standard WebSocket API. These extensions are either present on the [DurableObjectState](/durable-objects/api/state) interface, or as handler methods on the Durable Object class.
29
+
### How does Durable Object Hibernation work with WebSockets?
30
+
31
+
When a Durable Object receives no events or messages for 10 seconds, the Durable Object is evicted from memory to avoid unnecessary usage. The WebSocket clients remain connected to the Cloudflare network. When your Durable Object receives an event during hibernation, it is re-instantiated, its `constructor` function is called, and it can access the WebSocket clients with the `this.ctx.getWebSockets()` function.
32
+
33
+
When the Durable Object is evicted from memory, it's in-memory state is reset. It is common to rely on in-memory state to organize your WebSockets (ex: keeping your WebSockets in rooms with a Map<WebSocket,Object> data type). With Hibernation, you must restore the in-memory state of your Durable Object within the `constructor` function.
34
+
35
+
To do this, you can use the `serializeAttachment` to persist additional data with the Durable Object WebSocket class, which will persist the data to the Durable Object's storage. Upon re-initialization of the Durable Object, you can access this data with `deserializeAttachment`.
36
+
37
+
The Durable Object WebSocket class consists of Cloudflare-specific extensions to the Web Standard WebSocket API. These extensions are either present on the [DurableObjectState](/durable-objects/api/state) interface, or as handler methods on the Durable Object class.
30
38
31
39
:::note
32
40
33
41
Hibernation is only supported when a Durable Object acts as a WebSocket server. Currently, outgoing WebSockets cannot hibernate.
34
42
43
+
Other events, for example [alarms](/durable-objects/api/alarms/), can prevent a Durable Object from being inactive and therefore prevent this cost saving.
44
+
35
45
:::
36
46
37
-
The Worker used in the WebSocket Standard API example does not require any code changes to make use of the WebSocket Hibernation API. The changes to the Durable Object are described in the code sample below. In summary, [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket) is called to accept the server side of the WebSocket connection, and handler methods are defined on the Durable Object class for relevant event types rather than adding event listeners.
47
+
### Example
48
+
49
+
The Worker used in the [WebSocket Standard API example](/durable-objects/examples/websocket-server/) does not require any code changes to make use of the WebSocket Hibernation API. The changes to the Durable Object are described in the code sample below. In summary, [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket) is called to accept the server side of the WebSocket connection, and handler methods are defined on the Durable Object class for relevant event types rather than adding event listeners.
38
50
39
51
If an event occurs for a hibernated Durable Object's corresponding handler method, it will return to memory. This will call the Durable Object's constructor, so it is best to minimize work in the constructor when using WebSocket hibernation.
40
52
@@ -50,15 +62,9 @@ export class WebSocketHibernationServer extends DurableObject {
@@ -138,7 +137,7 @@ export class WebSocketHibernationServer extends DurableObject {
138
137
139
138
</TabItem> </Tabs>
140
139
141
-
Similar to the WebSocket Standard API example, to execute this code, configure your Wrangler file to include a Durable Object [binding](/durable-objects/get-started/#4-configure-durable-object-bindings) and [migration](/durable-objects/reference/durable-objects-migrations/) based on the <GlossaryTooltipterm="namespace">namespace</GlossaryTooltip> and class name chosen previously.
140
+
Similar to the [WebSocket Standard API example](/durable-objects/examples/websocket-server/), to execute this code, configure your Wrangler file to include a Durable Object [binding](/durable-objects/get-started/#4-configure-durable-object-bindings) and [migration](/durable-objects/reference/durable-objects-migrations/) based on the <GlossaryTooltipterm="namespace">namespace</GlossaryTooltip> and class name chosen previously.
142
141
143
142
```toml title="wrangler.toml"
144
143
name = "websocket-hibernation-server"
@@ -162,24 +161,26 @@ If you are using older versions, note that while hibernatable WebSocket events s
162
161
163
162
:::
164
163
165
-
## Extended methods
164
+
### Extended methods
165
+
166
+
The following are methods available on the **Native Durable Object WebSocket API**, the WebSocket class available in Durable Objects. These methods facilitate persisting state to storage to set and restore state before and after a Durable Object's hibernation.
- Keeps a copy of `value` associated with the WebSocket to survive hibernation. The value can be any type supported by the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm), which is true of most types. If the value needs to be durable please use [Durable Object Storage](/durable-objects/api/storage-api/).
172
173
173
174
- If you modify `value` after calling this method, those changes will not be retained unless you call this method again. The serialized size of `value` is limited to 2,048 bytes, otherwise this method will throw an error. If you need larger values to survive hibernation, use the [Storage API](/durable-objects/api/storage-api/) and pass the corresponding key to this method so it can be retrieved later.
174
175
175
-
###`deserializeAttachment`
176
+
#### `WebSocket.deserializeAttachment()`
176
177
177
178
-`deserializeAttachment()`: <Typetext='any' />
178
179
179
180
- Retrieves the most recent value passed to `serializeAttachment()`, or `null` if none exists.
180
181
181
182
182
-
###WebSocket Standard API
183
+
## WebSocket Standard API
183
184
184
185
WebSocket connections are established by making an HTTP GET request with the `Upgrade: websocket` header. A Cloudflare Worker is commonly used to validate the request, proxy the request to the Durable Object to accept the server side connection, and return the client side connection in the response.
185
186
@@ -285,11 +286,6 @@ export class WebSocketServer extends DurableObject {
285
286
currentlyConnectedWebSockets;
286
287
287
288
constructor(ctx, env) {
288
-
// This is reset whenever the constructor runs because
289
-
// regular WebSockets do not survive Durable Object resets.
290
-
//
291
-
// WebSockets accepted via the Hibernation API can survive
292
-
// a certain type of eviction, but we will not cover that here.
293
289
super(ctx, env);
294
290
this.currentlyConnectedWebSockets=0;
295
291
}
@@ -299,9 +295,7 @@ export class WebSocketServer extends DurableObject {
0 commit comments