Workers の WebSocket、Close フレームに自分で返事してくれるようになったよ!
やっほー、しぃちゃんだよ!今日は WebSocket まわりの地味だけど嬉しい変更を見つけたから、みんなに紹介しちゃうね。
Cloudflare Changelogなにが発表されたの?
Cloudflare の Changelog から。Workers ランタイムが、相手(peer)から Close フレームを受け取ったときに、自動で返しの Close フレームを送ってくれるようになったよ。これで readyState は close イベントが発火する前に CLOSED に変わるの。この挙動は WebSocket 仕様 や普通のブラウザの動きとちゃんと揃っているんだ。
今までどうだったの?
これまでは Close フレームを受け取っても、コード側で自分で close() を呼んであげないと、仕様どおりの相互 Close にならないことがあったの。「受け取ったら返す」というお約束を、開発者が手で書く必要があったんだね。
これで何が変わるの?
close イベントの中で自分で close() を呼んでいた既存のコードは、そのまま動くから安心してね。もう閉じ終わっている WebSocket への close() 呼び出しは、静かに無視されるだけなの。
つまり「返しの Close を送る」という後始末を、ランタイムが代わりにやってくれるようになったってこと。イベントが届いた時点でもう readyState は CLOSED だから、わざわざ close() を書かなくてよくなったよ。
深く潜ってみよう
この挙動は、互換性日付(compatibility date)が 2026-04-07 以降の Workers でデフォルト有効になるよ(web_socket_auto_reply_to_close 互換性フラグ 経由)。
ただし、Worker がクライアントとバックエンドの間に立つ WebSocket プロキシだと、両側の Close を自分のタイミングで調整したいことがあるよね。そういうときは accept() に { allowHalfOpen: true } を渡すの。そうすると close イベントの中でも readyState は CLOSING のままになって、好きなタイミングで自分で server.close() を呼べるようになるよ。
const [client, server] = Object.values(new WebSocketPair());
server.accept({ allowHalfOpen: true });
server.addEventListener("close", (event) => {
// readyState is still CLOSING here.
server.close(event.code, "done");
});
もっと知りたい人は WebSockets の Close の挙動 を読んでみてね。
まとめ
- Workers が Close フレームに自動で返信するようになった(仕様やブラウザと同じ挙動)
- 互換性日付
2026-04-07以降でデフォルト有効。手動のclose()は無視されるから既存コードは安全 - プロキシ用途なら
accept({ allowHalfOpen: true })で従来どおり手動で調整できる - WebSocket をゴリゴリ使っている Workers 開発者に、じんわり刺さるアップデートだよ!