Slide 1

Slide 1 text

# DurableObjects について
 Cloudflare Workers Tech Talks in Tokyo #3
 8/1 naporitan


Slide 2

Slide 2 text

## Take Home Message ● WebSocket は DurableObjects によって身近なものになった
 ● Hibernation API が便利
 ● ライブラリ作ったのでぜひ使ってください!


Slide 3

Slide 3 text

## 自己紹介 ● name: naporitan ○ twitter: naporin24690, github: naporin0624 ● hono/client を中心にコントリビューション ○ https://github.com/honojs/hono/graphs/contributors
 ● Cloudflare Workers をフロントエンドの拡張の視点から調査
 ○ y-durableobjects
 ○ Demo of `next/image` using Cloudflare Transform images


Slide 4

Slide 4 text

## 自己紹介

Slide 5

Slide 5 text

## 自己紹介

Slide 6

Slide 6 text

チャット機能どう作りますか?

Slide 7

Slide 7 text

## チャットどう作る? ● firestore
 ● pusher
 ● ロングポーリング


Slide 8

Slide 8 text

## Durable Objects 登場 ● id ごとに 1 つのオブジェクト対応
 ● 強整合な KV 付属
 ● JS RPC が利用できる
 ● WebSocket を払い出せる
 DurableObject 実装例


Slide 9

Slide 9 text

### id ごとに 1 つのオブジェクト ● 同じ id ならすべてのリクエストは1つのオブジェクトで処理される


Slide 10

Slide 10 text

### id ごとに 1 つのオブジェクト ● 同じ id ならすべてのリクエストは1つのオブジェクトで処理される


Slide 11

Slide 11 text

## 強整合な KV ● カウンターの作成可能
 ● カウンターと同様に RateLimit も作れる 


Slide 12

Slide 12 text

### JS RPC ● class で定義した method が使える
 ● chimame さんの記事がわかりやすいです


Slide 13

Slide 13 text

## Durable Objects 利用先 ● リクエストカウンタ
 ● リアルタイムチャット
 ● ゲーム
 ● 共同編集
 ● OBS Overlay


Slide 14

Slide 14 text

今回は DurableObjects で WebSocket を扱うための Tips を紹介します

Slide 15

Slide 15 text

## Durable Objects で WebSocket を扱う ● Hibernation API
 ● ping/pong
 ● JS RPC


Slide 16

Slide 16 text

## Durable Objects で WebSocket を扱う ● Hibernation API
 ● ping/pong
 ● JS RPC


Slide 17

Slide 17 text

### Hibernation API とは ● サーバーが休止状態になる
 ○ 接続を維持したまま休止する 
 ○ 休止している間は料金が発生しない 
 ● 専用 API が存在する
 ○ webSocketMessage
 ○ webSocketError
 ○ webSocketClose
 ○ etc…


Slide 18

Slide 18 text

### サーバーが休止状態になるとは ● だいたい 5 ~ 10s message のやり取りがないと閉じられる
 ○ class の状態はサーバーが休止状態になる度に揮発する 
 ○ 永続化したい状態を保存するときは Transaction Storage に入れる
 ● メソッドが呼ばれると起動
 ○ WebSocket イベント・alarm・JS RPC
 ● constructor で非同期処理をするときは blockConcurrencyWhile を使用する


Slide 19

Slide 19 text

## Durable Objects で WebSocket を扱う ● Hibernation API
 ● ping/pong
 ● JS RPC


Slide 20

Slide 20 text

### ping/pong ● 死んだコネクションを自動的に切りたい
 ○ ws の ping 相当が欲しい
 ● ping/pong frame でやり取りしてる
 ○ WebSocket サーバーの記述 - Web API | MDN
 ○ ping は 0x09, pong は 0xA


Slide 21

Slide 21 text

#### WebSocket には ping/pong frame がない ● Web API の WebSocket には ping/pong frame を送信する術がない
 ○ Sending websocket ping/pong frame from browser - Stack Overflow
 ○ https://websockets.spec.whatwg.org/#ping-and-pong-frames
 ■ > These are not currently exposed in the API.


Slide 22

Slide 22 text

### ping/pong ● 特定の message でやり取りする
 ○ client から ping が来たら server で pong する(逆でも可)
 ○ Hibernation API を利用してる場合、休止状態から復帰してしまう 
 ■ クライアント数増加に伴い休止する時間が少なくなる 
 ● 意味ない


Slide 23

Slide 23 text

壊れた接続の検出と コネクションの停止 はどうする?

Slide 24

Slide 24 text

DurableObjects の API と Hibernation API を 組み合わせることで解決できる

Slide 25

Slide 25 text

#### 接続の監視と停止 ● 休止状態のまま返答する API
 ● 接続の定期確認
 ● 自動返答した時間を確認する API
 ● WebSocket に値を埋め込む 


Slide 26

Slide 26 text

#### 接続の監視と停止 ● 休止状態のまま返答する API
 ○ WebSocketRequestResponsePair
 ○ setWebSocketAutoResponse


Slide 27

Slide 27 text

#### 接続の監視と停止 ● 自動返答した時間を確認する API
 ○ getWebSocketAutoResponseTimestamp
 ● WebSocket に値を埋め込む 
 ○ serializeAttachment


Slide 28

Slide 28 text

#### 接続の監視と停止 ● 接続の定期確認
 ○ setAlarm
 ○ alarm


Slide 29

Slide 29 text

## Durable Objects で WebSocket を扱う ● Hibernation API
 ● ping/pong
 ● JS RPC


Slide 30

Slide 30 text

### DurableObject JS RPC ● WebSocket が JS RPC でサポートされていない
 ○ https://github.com/cloudflare/workerd/issues/2319
 JS RPC で WebSocket を払い出す
 RPC 経由で WebSocket を返す


Slide 31

Slide 31 text

### DurableObject JS RPC ● WebSocket が JS RPC でサポートされていない
 ○ https://github.com/cloudflare/workerd/issues/2319
 WebSocket は Serialize できずエラー


Slide 32

Slide 32 text

WebSocket は fetch で 払い出す必要がある

Slide 33

Slide 33 text

Hono RPC と組み合わせて型安全を得る

Slide 34

Slide 34 text

### JS RPC + Hono RPC ● fetch で WebSocket の発行
 ● RPC でその他ロジック実行


Slide 35

Slide 35 text

### JS RPC + Hono RPC ● fetch で WebSocket の発行
 ● RPC でその他ロジック実行


Slide 36

Slide 36 text

### JS RPC + Hono RPC ● fetch で WebSocket の発行
 ● RPC でその他ロジック実行


Slide 37

Slide 37 text

### JS RPC + Hono RPC ● fetch で WebSocket の発行
 ● RPC でその他ロジック実行


Slide 38

Slide 38 text

### JS RPC + Hono RPC ● ロジックを method で定義
 ● Hono で fetch 経由で method 実行


Slide 39

Slide 39 text

### JS RPC + Hono RPC ● ロジックを method で定義
 ● Hono で fetch 経由で method 実行


Slide 40

Slide 40 text

### JS RPC + Hono RPC ● ロジックを method で定義
 ● Hono で fetch 経由で method 実行


Slide 41

Slide 41 text

### JS RPC + Hono RPC

Slide 42

Slide 42 text

Client 側でも Hono RPC を利用する

Slide 43

Slide 43 text

### Hono RPC(Client) ● upgrade ミドルウェアを作る
 ● outputFormat を設定することで PRC に WebSocket を返すことを伝える


Slide 44

Slide 44 text

### Hono RPC(Client) ● upgrade ミドルウェアを設定


Slide 45

Slide 45 text

### Hono RPC(Client) ● Client 側でも WebSocket の呼び出しができる


Slide 46

Slide 46 text

### Hono RPC(Client) ● 再接続可能な WebSocket にも対応できるように PR を出しています
 ● このように利用できるようになるかも...?


Slide 47

Slide 47 text

## ライブラリを作りました ● Hibernation API 搭載
 ● 接続の監視と停止
 ● WebSocket の払い出し
 https://github.com/napolab/durabcast


Slide 48

Slide 48 text

End

Slide 49

Slide 49 text

## (おまけ) PartyKit ● Durable Objects を扱うためのもう一つのやり方
 ● Hibernation API が option 1 つで切り替えられる
 ● Cloudflare Workers と Durable Objects を 1 つの class で定義
 ○ onStart, onConnect, onRequest など直感的な interface を採用
 ● yjs のサーバー実装・client 実装もあるためアプリケーションに組み込みやすくなっ ている


Slide 50

Slide 50 text

## (おまけ) PartyKit ● OSS だがビルドサーバーが partykit 側にあるため最終成果物がどうなっているか わからない
 ● binding を自由に設定することができない
 ○ ダッシュボードからの設定も不可能