
WebTransportを試す
WebTransportをAWS環境で動作させるまでの道のり
背景
なにか、尖ったリアルタイム通信がしたいなーと思い立ち、調べていると、AIヒアリングかけるとだいたいこんな感じらしい
純粋なgRPC ー> ブラウザからは直接呼べない
gRPC-Web ー> サーバーからのストリームのみ可
Connect ー> Web開発における現在の主流
WebSocket ー> 古典的だが確実。
とはいえ、事例がすくないものをやるほうが面白いな。ということになり、WebTransportに手を出すことにする。
WebTransportについては以下 https://developer.chrome.com/docs/capabilities/web-apis/webtransport?hl=ja
https://github.com/quic-go/webtransport-go goの実装がここにあったので、これを元にして、実装してみよう。
Webブラウザのチェック
chrome://flags
上記にアクセスして、設定をEnabledにしておく(もしかしたら、この設定をしておけば証明書の発行いらんかった?)

証明書周りの課題
webTransportを実験する際は、localhostであってもhttpsによる通信を行いたいため、mkcertを利用する。また、今回はアプリが直接TLSを処理する必要があったため、証明書をエクスポート可能な環境を用意する。
https://github.com/FiloSottile/mkcert
mkcertでPC内に認証局を用意して、localhostでもhttpsを実現する。
mkcert --install
mkcert localhost
AWS環境では?
let’s Encryptを利用して、証明書を獲得する。 一日1回動くLambdaを用意して、証明書のチェック、更新をおこなう。
ECSアプリケーションをインターネットに接続する。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/networking-outbound.html
本来はNLBとかをたてて、そこを中継するほうが筋がいいんだろうけど、NLBたてるとコストが高いので実験のためにそこまでやるのもなーとなったので、今回はECSを上記の方法でつなげる。 当たり前ですがもっとちゃんとやる場合はNLB使うなりしましょう。
動作確認
ここで疎通確認 https://webtransport.day/

あと気が済んだら消す予定の今回つくったサイト https://wt.muzigen.net:8443/
mermaid
flowchart TB
subgraph Client["クライアント"]
Browser["ブラウザ<br/>(Chrome/Edge)"]
end
subgraph Squarespace["Squarespace DNS"]
NS["NS レコード<br/>wt.muzigen.net → Route53"]
end
subgraph AWS["AWS"]
subgraph Route53["Route53"]
HostedZone["Hosted Zone<br/>wt.muzigen.net"]
ARecord["A レコード<br/>→ ECS Public IP"]
end
subgraph ECS["ECS Fargate"]
Task["ECS Task"]
subgraph Container["コンテナ"]
Server["WebTransport Server<br/>:4433 UDP/TCP"]
Static["Static Server<br/>:8443 TCP"]
DNSScript["DNS更新スクリプト"]
end
end
subgraph SecretsManager["Secrets Manager"]
Cert["証明書<br/>CERT_CONTENT<br/>KEY_CONTENT"]
end
subgraph Lambda["Lambda"]
Rotator["証明書更新<br/>(1日1回)"]
end
subgraph LetsEncrypt["Let's Encrypt"]
ACME["ACME Server"]
end
EventBridge["EventBridge<br/>スケジュール"]
end
%% クライアント接続フロー
Browser -->|"1. DNS解決"| NS
NS -->|"2. 委任"| HostedZone
HostedZone --> ARecord
ARecord -->|"3. IP取得"| Browser
Browser -->|"4. HTTPS :8443"| Static
Browser -->|"5. WebTransport<br/>QUIC :4433"| Server
%% 証明書フロー
EventBridge -->|"トリガー"| Rotator
Rotator -->|"DNS-01 チャレンジ"| HostedZone
Rotator -->|"証明書要求"| ACME
ACME -->|"検証"| HostedZone
ACME -->|"証明書発行"| Rotator
Rotator -->|"保存"| Cert
%% ECS起動フロー
Task -->|"証明書取得"| Cert
DNSScript -->|"IP更新"| ARecord
%% スタイル
classDef aws fill:#FF9900,stroke:#232F3E,color:#232F3E
classDef client fill:#4285F4,stroke:#333,color:#fff
classDef external fill:#0F9D58,stroke:#333,color:#fff
class Route53,ECS,SecretsManager,Lambda,EventBridge aws
class Browser client
class LetsEncrypt,Squarespace external
sequenceDiagram
participant EB as EventBridge
participant Lambda as Lambda
participant R53 as Route53
participant LE as Let's Encrypt
participant SM as Secrets Manager
participant ECS as ECS Task
Note over EB,ECS: 証明書更新フロー (1日1回)
EB->>Lambda: スケジュール実行
Lambda->>SM: 現在の証明書を取得
Lambda->>Lambda: 有効期限チェック<br/>(30日以内?)
alt 更新が必要
Lambda->>LE: 証明書要求 (ACME)
LE->>Lambda: DNS-01 チャレンジ
Lambda->>R53: TXTレコード作成<br/>_acme-challenge.wt
Lambda->>LE: チャレンジ完了通知
LE->>R53: TXTレコード検証
LE->>Lambda: 証明書発行
Lambda->>SM: 新しい証明書を保存
Lambda->>R53: TXTレコード削除
end
Note over EB,ECS: ECS タスク起動フロー
ECS->>SM: 証明書を取得
SM->>ECS: CERT_CONTENT, KEY_CONTENT
ECS->>ECS: TLS設定
ECS->>R53: Aレコード更新<br/>(Public IP)
ECS->>ECS: サーバー起動