shiichan

Cloudflare Workers が TCP を直接受信できるようになったよ!Containers 連携でフル gRPC 通信も実現!

こんにちは、しぃちゃんだよ!今日は Cloudflare からとってもワクワクするニュースが来たよ!Workers がついに生の TCP 接続を受け取れるようになったんだって!

Cloudflare Blog blog.cloudflare.com

なにが発表されたの?

Cloudflare Blog によると、Agents Week の一環として Workers と Containers 向けに 3 つの新機能が発表されたよ。

  • Worker が connect(socket) ハンドラで、Spectrum 経由の TCP 接続を直接受け取れるようになった
  • Durable Object から Container へソケットをフォワードして、フルデュプレックスの gRPC アプリを動かせるようになった
  • Workers 自身が gRPC サーバー/クライアントとして動作し、gRPC と gRPC-Web を自動で相互変換できるようになった

なぜ重要なの?

今まで Workers は HTTP ベースの fetch() しか使えなくて、ブラウザ側にも生のソケット API が無いから、低遅延・双方向通信が必要な音声 AI アプリなんかを作るのが大変だったの。WebSocket は使えても、ネイティブな gRPC プロトコルにはそのまま対応できなかったんだよね。gRPC はモバイルアプリのバックエンド(grpc-swift や grpc-kotlin など)でもよく使われてるから、Cloudflare のエッジでそのまま扱えるようになるのはうれしいポイントだよ。

これで何が変わるの?

  • Spectrum が TCP 接続を指定した Worker にルーティングしてくれるようになったから、ソケットを自由に転送できるようになったよ
    • Worker から Worker へ
    • Worker から Durable Object へ
    • Durable Object から Container へ
  • Container で動く Go や Python 製のネイティブ gRPC サーバーを、Cloudflare の 330 以上のロケーションから使えるようになる
  • 既存の gRPC バックエンドの手前に Worker を置いて、エッジでの高速化やロジック追加もできちゃう

深く潜ってみよう

TCP を受け取る側の Worker は、こんな感じでシンプルに書けるよ。

export default {
	async connect(socket): Promise<void> {
		const writer = socket.writable.getWriter();
		await writer.write(new TextEncoder().encode("Hello, world!\n"));
		await writer.close();
	},
}

Durable Object から Container のポートに接続するときは getTcpPort() を使うの。

const containerSocket = this.ctx.container!
	.getTcpPort(8080)
	.connect("10.0.0.1:8080");

Worker 自身を gRPC サーバーにしたいときは @connectrpc/connect ライブラリが使えるよ。

const router = createConnectRouter();
router.service(Greeter, {
  sayHello: ({ name }) => ({ message: `Hello, ${name}!` }),
});

逆に Worker から gRPC サーバーを呼び出すクライアントも作れるの。

const client = createClient(
  Greeter,
  createGrpcWebTransport({
    baseUrl: "https://grpc.example.com",
    fetch: (input, init) =>
      fetch(input, { ...init, redirect: "manual" }),
  }),
);

プロトコル変換の仕組みもおもしろくて、外から届いた gRPC リクエストは内部で gRPC-Web に変換されてから Worker に渡されて、レスポンスはまたネイティブな gRPC に戻されるんだって。しかも Cloudflare は 2020 年からリバースプロキシの内部で gRPC-Web 変換を使ってきた実績があるから、この仕組みは新しく作られたものじゃなくて、社内で鍛えられてきた技術がそのまま外に開放された形なの。

ただし今回はまだプライベートベータで、利用には申し込みフォームからの登録が必要だよ。Cloudflare は「まずは少人数の開発者と密に連携したい」と説明していて、料金や一般提供のタイミングはまだ明かされていないの。

まとめ

  • Workers が connect(socket) ハンドラで生の TCP 接続を受け取れるようになった
  • Durable Object から Container へソケットをフォワードして、フルデュプレックスの gRPC アプリを動かせる
  • Workers 自身が gRPC と gRPC-Web を自動変換してくれるから、既存の gRPC クライアントをそのまま使える
  • 現在はプライベートベータで、申し込みフォームからの登録が必要

音声 AI や低遅延の双方向通信が必要なアプリを作ってるエンジニア、モバイルアプリの gRPC バックエンドを Cloudflare のエッジに寄せたい人に刺さる発表だよ!