コンテンツにスキップ

WebSockets APIの使用

WebSockets APIを使用して、Cloudflare Workersとリアルタイムで通信します。

WebSocketsを使用すると、Cloudflare Workersのサーバーレス関数とリアルタイムで通信できます。このガイドでは、Cloudflare WorkersにおけるWebSocketsの基本を学びます。これは、Workers関数内でWebSocketサーバーを作成する視点と、クライアントとしてそれらのWebSocketサーバーに接続して作業する視点の両方を含みます。

WebSocketsは、クライアントとオリジンサーバーの間で維持されるオープンな接続です。WebSocket接続内では、クライアントとオリジンがデータを行き来させることができ、セッションを再確立する必要がありません。これにより、WebSocket接続内でのデータ交換が迅速になります。WebSocketsは、ライブチャットやゲームなどのリアルタイムアプリケーションでよく使用されます。

WebSocketサーバーの作成

Cloudflare WorkersのWebSocketサーバーを使用すると、クライアントからリアルタイムでメッセージを受信できます。このガイドでは、WorkersでWebSocketサーバーを設定する方法を示します。

クライアントは、WebSocketの新しいインスタンスを作成し、Workers関数のURLを渡すことで、ブラウザでWebSocketリクエストを行うことができます:

// クライアント側のJavaScriptで、WebSocketsを使用してWorkers関数に接続します:
const websocket = new WebSocket('wss://example-websocket.signalnerve.workers.dev');

受信したWebSocketリクエストがWorkers関数に到達すると、それにはUpgradeヘッダーが含まれ、文字列値websocketに設定されます。このヘッダーを確認してからWebSocketをインスタンス化する必要があります:

async function handleRequest(request) {
const upgradeHeader = request.headers.get('Upgrade');
if (!upgradeHeader || upgradeHeader !== 'websocket') {
return new Response('Expected Upgrade: websocket', { status: 426 });
}
}

Upgradeヘッダーを適切に確認した後、サーバーとクライアントのWebSocketを含む新しいWebSocketPairのインスタンスを作成できます。これらのWebSocketの1つはWorkers関数によって処理され、もう1つは101ステータスコードを持つResponseの一部として返され、リクエストがプロトコルを切り替えていることを示します:

async function handleRequest(request) {
const upgradeHeader = request.headers.get('Upgrade');
if (!upgradeHeader || upgradeHeader !== 'websocket') {
return new Response('Expected Upgrade: websocket', { status: 426 });
}
const webSocketPair = new WebSocketPair();
const client = webSocketPair[0],
server = webSocketPair[1];
return new Response(null, {
status: 101,
webSocket: client,
});
}

WebSocketPairコンストラクタは、01のキーを持つオブジェクトを返し、それぞれがWebSocketインスタンスを値として保持します。このペアから2つのWebSocketを取得するために、Object.valuesES6の分割代入を使用することが一般的です。以下の例に示すように。

Worker内のclient WebSocketとの通信を開始するには、server WebSocketでacceptを呼び出します。これにより、WorkersランタイムはWebSocketデータをリッスンし、client WebSocketとの接続を維持する必要があることを示します:

async function handleRequest(request) {
const upgradeHeader = request.headers.get('Upgrade');
if (!upgradeHeader || upgradeHeader !== 'websocket') {
return new Response('Expected Upgrade: websocket', { status: 426 });
}
const webSocketPair = new WebSocketPair();
const [client, server] = Object.values(webSocketPair);
server.accept();
return new Response(null, {
status: 101,
webSocket: client,
});
}

WebSocketsは、addEventListenerを使用して接続できる多くのイベントを発生させます。以下の例は、messageイベントにフックし、そのデータをconsole.logで出力します:

async function handleRequest(request) {
const upgradeHeader = request.headers.get('Upgrade');
if (!upgradeHeader || upgradeHeader !== 'websocket') {
return new Response('Expected Upgrade: websocket', { status: 426 });
}
const webSocketPair = new WebSocketPair();
const [client, server] = Object.values(webSocketPair);
server.accept();
server.addEventListener('message', event => {
console.log(event.data);
});
return new Response(null, {
status: 101,
webSocket: client,
});
}

クライアントからWebSocketサーバーに接続する

Workers関数と通信するWebSocketクライアントを書くことは、2段階のプロセスです。まず、WebSocketインスタンスを作成し、次にそれにイベントリスナーを追加します:

const websocket = new WebSocket('wss://websocket-example.signalnerve.workers.dev');
websocket.addEventListener('message', event => {
console.log('サーバーからメッセージを受信しました');
console.log(event.data);
});

WebSocketクライアントは、send関数を使用してサーバーにメッセージを送信できます:

websocket.send('MESSAGE');

WebSocketのやり取りが完了したら、クライアントはcloseを使用して接続を閉じることができます:

websocket.close();

これを実践での例として、websocket-templateを参照してWebSocketsを始めてください。

WebSocketクライアントの作成

Cloudflare Workersはnew WebSocket(url)コンストラクタをサポートしています。Workerは、上記で説明したクライアント実装と同様に、リモートサーバーにWebSocket接続を確立できます。

さらに、Cloudflareは、Upgradeヘッダーが設定されたURLに対してフェッチリクエストを行うことでWebSocket接続を確立することをサポートしています。

async function websocket(url) {
// `Upgrade: websocket`ヘッダーを含むフェッチリクエストを行います。
// Workersランタイムは、Sec-WebSocket-Keyヘッダーなど、WebSocketプロトコルの他の要件を自動的に処理します。
let resp = await fetch(url, {
headers: {
Upgrade: 'websocket',
},
});
// WebSocketハンドシェイクが正常に完了した場合、レスポンスには`webSocket`プロパティがあります。
let ws = resp.webSocket;
if (!ws) {
throw new Error("サーバーがWebSocketを受け入れませんでした");
}
// accept()を呼び出して、ここでJavaScriptでソケットを処理することを示します。
// クライアントに返すのではなく。
ws.accept();
// これで、以前のようにメッセージを送受信できます。
ws.send('hello');
ws.addEventListener('message', msg => {
console.log(msg.data);
});
}

WebSocket圧縮

Cloudflare WorkersはWebSocket圧縮をサポートしています。詳細については、WebSocket圧縮を参照してください。