Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cloudflare Realtime と Workers でつくるサーバーレス WebRTC
Search
Taiyu Yoshizawa
June 03, 2025
Programming
1.9k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Cloudflare Realtime と Workers でつくるサーバーレス WebRTC
Taiyu Yoshizawa
June 03, 2025
More Decks by Taiyu Yoshizawa
See All by Taiyu Yoshizawa
The Present and Future of CJK Rendering in MapLibre
nekoya3
0
7
Kartore: A Style Editor and Toolkit for MapLibre
nekoya3
0
9
Kartore: Maplibre のための Style Editor とその Toolkit
nekoya3
0
26
Flagship という素晴らしいもの / This awesome thing called Flagship
nekoya3
0
2
10分で完全に理解出来る Cloudflare Workers + HyperDrive / Cloudflare Workers + HyperDrive: You Might Understand It in Just 10 Minutes
nekoya3
0
12
WorkersでCMSを作ってみないか / Wanna build a CMS with Workers?
nekoya3
0
9
北海道新型コロナウイルスまとめサイトでのいろいろなこと
nekoya3
0
470
Other Decks in Programming
See All in Programming
Hono + Inertia + React で LP を構築した話
oukayuka
2
210
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
260
高専キャリア LT 発表内容
crysta1221
6
5.5k
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
150
私のClaude Code活用法 (個人開発編) - PHPerKaigi mini #4(2026/08/24)
panda_program
1
210
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
110
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
220
バグを直したら useEffect が消えた
colorful12
3
840
[KotlinConf Extended South Korea 2026] KotlinConf 2026 발표자 후기
wisemuji
0
100
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
120
이 함수, 실패하면 어떻게 되나요? null부터 Rich Errors까지, Kotlin 에러 처리 15년
haeti2
0
130
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
160
Featured
See All Featured
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
560
GraphQLとの向き合い方2022年版
quramy
50
15k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
600
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Fireside Chat
paigeccino
42
4k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.9k
How to Talk to Developers About Accessibility
jct
2
540
Transcript
Cloudflare Workers + Realtime ɴᴇᴋᴏʏᴀsᴀɴ
Who are you? g ɴᴇᴋᴏʏᴀsᴀ g Software Engineer @MIERUNE Inc1
g Co-founder & Software Engineer @ ReMotivI g GitHub: @NEKOYASA2 g Web: nekoyasan.me
What is MIERUNE 位置情報技術に特化したプロフェッショナル集 9年前に北海道のOSSコミュニティ (FOSS4G) から創業し て、現在も本社は札幌市、社員数38
OSSを中心に柔軟な技術選定を実D Hono / Svelte / Maplibre / QGIS などな" HP: https://www.mierune.co.jp/
れきちず | MapLibre | 地理院タイル | 『日本歴史地名大系』地名項目データセット れきちず:https://rekichizu.jp/
おことわり V 今回は Cloudflare Realtime について様々な用語の説明をし ながらお話しまy V 用語の中には仕様上はかなり複雑なものもあり、とっつきやす いように端折っている箇所も多くありまy
V 私自身も専門家というわけではない一利用者に過ぎないため、 誤った箇所などあればお教えください
Cloudflare Realtime とは
Cloudflare Realtime とは Cloudflare が提供する WebRTC に関連するサービスの総Q 以前は
Cloudflare Calls という名称でサービス提供がされて いたが、2025年4月に名称変s 名称変更と同タイミングで正式リリース & Realtime Kit の Private Beta が開始
Cloudflare Realtime とは Cloudflare が提供する WebRTC に関連するサービスの総Q 以前は
Cloudflare Calls という名称でサービス提供がされて いたが、2025年4月に名称変s 名称変更と同タイミングで正式リリース & Realtime Kit の Private Beta が開始
WebRTCとは x Web RealTime Communication → Web RT7 x 双方向リアルタイム通信を実現するためのAPIやプロトコルのこ
とを指すb x RFC8825 ~ 8839 あたりを中心に定義されているが、関連す る仕様なども合わせると非常に多岐にわたv x 現在ではブラウザに標準機能として基本的には搭載されており、 双方向リアルタイム通信の手法としては比較的利用しやすい
WebRTCとは Discord や Google Meet 、 Twitter Spaces など、音声通
話やビデオ通話等に多く利用されているT 最近では WHIP や WHEP という規格によってOBSなどソフ トウェアを使った配信にも活用できるような基盤が整い始めてい WebRTCの詳しいことは専門の会社さんが記事などでまとめて くれているのでそちらへ...
WebRTCとは STU TUR SFU
STUNとは u Session Traversal Utilities for NATs = STU% u
NAT環境下に自身が居る場合にデバイスはプライベートIPしか わからず、そのままでは自身のグローバルIPがわからない → STUNに問い合わせることで知ることができる
STUNとは クライアント N A T 私は...どこのだれ...? ...
STUNとは クライアント STUN サーバー N A T Binding Request Binding
Response 私は...どこのだれ...? あなたはこのIP / Port
TURNとは n Traversal Using Relays around NAT = TURb n
P2P による直接通信が出来ない(STUNだけではP2Pでの接続 が確立できない)or UDPによる接続が確立できない場合に利用 する中継サーバ・プロトコルのこi n サーバを経由するがただのバイパスしか役目がなく、バイパスし ているデータを読み取ることも、変化させることもなf n サーバを経由するため、P2Pに比べて遅延は大きくなってしまう
TURNとは クライアント クライアント
TURNとは クライアント クライアント TURN サーバー
SFUとは m Selective Forwarding Unit = SFv m P2P による通信ではメッシュ接続をする必要があるため参加者
が増えるにつれて、1人が接続する接続数が増大する問題があf m SFUサーバとの接続のみを行い、SFUサーバーが必要に応じて 他のクライアントに転送すf m 転送しか出来ず加工をすることは出来な' m 対照的に合成・再エンコードを行うMCUも存在する
SFUとは やばい
SFUとは SFU サーバー
WebRTCとは STU TUR SFU
Cloudflare Realtime では 2 Realtime Ki0 2 TURN Serve 2
Serverless SFU
Cloudflare Realtime では 5 Realtime Ki2 5 TURN Serve 5
Serverless SF# 5 (STUN Server)
Cloudflare Realtime では F Realtime KiD F TURN Serve' F
Serverless SF3 F (STUN Server) で提供はされている stun.cloudflare.com:3478
Cloudflare Realtime では F Realtime KiD F TURN Serve' F
Serverless SF3 F (STUN Server) で提供はされている stun.cloudflare.com:3478
Cloudflare Realtime では F Realtime KiD F TURN Serve' F
Serverless SF3 F (STUN Server) で提供はされている stun.cloudflare.com:3478
TURN Server f TURN サーバーの Cloudflare フルマネージドなもb f TURN Key
IDと Token から TURN Username と Credentialを作り、それらとurlsをiceServersで設定すQ f GraphQL の Analytics API が用意されていて、どれだけ利用 されているか、不正利用の検知が出来Q f EdgeからのEgress のみが課金対u f 0.05 USD / GB で 初回1000GBまでは無 f カスタムドメインを割り当てることも出来る
Serverless SFU l SFU の Cloudflare フルマネージドなもs l PeerConnection で
Session を作り、MediaStreamTrack (Audio / Video) をトラックとして持y l ルームという概念はなく、トラックそれぞれに一意のIDが付いて いて、それをグローバルなどこからでも取得することができ# l 取得していなければ課金もされないので、メディアストリームを 動的につなぎ替えることができるスイッチャーのような役目を 担っているとも言える
Realtime Kit j まだPrivate Betaで全容がよくわからないものの.. j クライアントのSDK・UIが用意されていたV j RecordingやAnalytics、Workers AI
との連) j Realtime AIと称し て Transcription や Agent、Voice AI、 ノイズキャンセルなどの連携が用意されているよ j ベース技術とし てはServerless SFU / TURN Serverなのは変 化がなく、ユーザー認証やルーム機能などが含まれていて、即使 える!みたいなもの?
ここからは Serverless SFU 使ったデモ
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20 const new const await const return peerConnection RTCPeerConnection({ iceServers [ { urls , }, ], bundlePolicy , }); localStream navigator.mediaDevices. ({ video , audio , }); transceivers localStream. (). ((track) { peerConnection. (track, { direction , }); }); = : : : = : : = => : "stun:stun.cloudflare.com:3478" "max-bundle" "sendonly" getUserMedia getTracks map addTransceiver true true
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20 await await const await const await peerConnection. ( peerConnection. ()); response ( , { method , headers { , Authorization ${appSecret} , }, body . ({ sessionDescription { type , sdp peerConnection.localDescription.sdp, }, }), }, ); newSessionResult response. (); setLocalDescription createOffer fetch stringify json = : : : : : : : : = "https://rtc.live.cloudflare.com/v1/apps/${appId}/sessions/new" "POST" "application/json" `Bearer ` "offer" "Content-Type" JSON
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 trackObjects transceivers. ((transceiver) { { location , mid transceiver.mid , trackName transceiver.sender.track.id, }; }); peerConnection. ( peerConnection. ()); newLocalTrackResult app. ( trackObjects, peerConnection.localDescription.sdp, ); peerConnection. ( RTCSessionDescription(newLocalTrackResult.sessionDescription), ); = => : : ?? : = map setLocalDescription createOffer newTracks setRemoteDescription return await await const await await new "local" "1" // POST /session/sessionid/tracks/new
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 if switch case await new await await await break case throw new (newRemoteTracksResult.sessionDescription) { (newRemoteTracksResult.sessionDescription.type) { . ( ${sessionId} ); peerConnection. ( RTCSessionDescription(newRemoteTracksResult.sessionDescription), ); peerConnection. ( peerConnection. (), ); app. (peerConnection.localDescription.sdp); ; Error( ); } } "offer" `Renegotiating for session ` "answer" "An offer SDP was expected" : console : log setRemoteDescription setLocalDescription createAnswer sendAnswerSDP
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 const new let if const await const new return remoteTrackPromise ((resolve) { tracks []; peerConnection. (event) { tracks. (event.track); . ( ${event.track.id} ${event.track.mid} ); (tracks.length ) { (tracks); } }; }); remoteTracks remoteTrackPromise; remoteStream MediaStream(); remoteTracks. ((track) { remoteStream. (track); }); remoteStream; = Promise => = = => console >= = = => ontrack push debug resolve forEach addTrack `Got track mid= ` 2
まとめ 現状だとまだある程度 WebRTC の初期知識が必要で、すぐに 簡単に使える!というものではなD ある意味無限スケーリングするSFU・TURN Serverというもの がほぼ初めて存在しているので、何か面白いことが出来そうなも
のではあi DataChannelとかも使える & WHIPの参考実装などもあi Realtime Kitたのしみ!
Cloudflare Realtime ぜひ遊んでみてね!