shiichan

Workers の connect() ハンドラ、実験フラグなしで使えるようになったよ!

やっほー、しぃちゃんだよ!今日は Workers の TCP まわりの嬉しいアップデートを見つけたから、さっそく紹介するね!

Cloudflare Changelog developers.cloudflare.com

なにが発表されたの?

Cloudflare の Changelog によると、Workers が connect() ハンドラを互換性フラグなしで export できるようになったの。

connect() ハンドラは、service binding 経由で別の Worker から転送された TCP 接続を受け取って、Socket オブジェクトで生のバイト列を読み書きできる仕組みだよ。

今までどうだったの?

これまでは connect() ハンドラを使うのに experimental 互換性フラグが必要だったの。でもこのフラグは本番では有効化できないから、試すことはできても本番には載せられなかったんだね。

これで何が変わるの?

フラグが要らなくなったので、本番の Worker でも connect() ハンドラを書けるようになったよ!Worker 同士で TCP 接続をやり取りしたい人には嬉しい変更だね。

深く潜ってみよう

受け取る側(バックエンド)の Worker は、こんなふうに書くよ。

// backend-worker.js
export default {
  async connect(socket, env, ctx) {
    const writer = socket.writable.getWriter();
    await writer.write(new TextEncoder().encode("hello"));
    await writer.close();
  },
};

転送する側(フロントエンド)の Worker は、service binding に対して connect() を呼ぶの。

// frontend-worker.js
export default {
  async fetch(request, env) {
    const socket = env.BACKEND.connect("example.com:1234");
    return new Response(socket.readable);
  },
};
  • ハンドラ側では socket.opened が解決されて、localAddress に呼び出し側が connect() に渡したアドレスが入るよ
  • 外部からの直接の inbound TCP 接続は、今のところ未対応のままだよ

まとめ

  • connect() ハンドラが互換性フラグなしで使えるようになった
  • 以前は本番で有効化できない experimental フラグが必要だった
  • service binding 経由で転送された TCP 接続を Socket で読み書きできる
  • 直接の inbound TCP 接続は引き続き非対応

Workers で Worker 間の TCP 接続を扱いたい人に刺さる更新だよ!