From 6d40d55cf966f7b3cb1995fdf4deb3f058fb9000 Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Sat, 28 Sep 2024 18:42:29 +0900 Subject: [PATCH 1/2] =?UTF-8?q?2024/09/16=20=E6=99=82=E7=82=B9=E3=81=AE?= =?UTF-8?q?=E8=8B=B1=E8=AA=9E=E7=89=88=E3=81=AB=E5=9F=BA=E3=81=A5=E3=81=8D?= =?UTF-8?q?=E6=96=B0=E8=A6=8F=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../using_websocketstream/index.md | 301 ++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 files/ja/web/api/websockets_api/using_websocketstream/index.md diff --git a/files/ja/web/api/websockets_api/using_websocketstream/index.md b/files/ja/web/api/websockets_api/using_websocketstream/index.md new file mode 100644 index 00000000000000..b86bf016acd7f2 --- /dev/null +++ b/files/ja/web/api/websockets_api/using_websocketstream/index.md @@ -0,0 +1,301 @@ +--- +title: WebSocketStream でクライアントを書く +slug: Web/API/WebSockets_API/Using_WebSocketStream +l10n: + sourceCommit: d102514706e844bd642850aa340c9645c74bf70c +--- + +{{DefaultAPISidebar("WebSockets API")}}{{non-standard_header}} + +{{domxref("WebSocketStream")}} API は、{{jsxref("Promise", "プロミス", "", 1)}}ベースのもうひとつの選択肢であり、クライアントサイドの WebSocket 接続の作成と使用にWebSocket を使用します。 `WebSocketStream` は、[ストリーム API](/ja/docs/Web/API/Streams_API) を使用してメッセージの送受信を処理するため、ソケット接続はストリームの[背圧](/ja/docs/Web/API/Streams_API/Concepts#背圧)を自動的に利用することができ(開発者による追加の操作は不要)、アプリケーションのボトルネックを回避するために読み取りまたは書き込みの速度を調整することができます。 + +この記事では、{{domxref("WebSocketStream")}} API を使用して WebSocket クライアントを作成する方法を説明します。 + +## 機能検出 + +`WebSocketStream` API に対応しているかどうかを確認するには、次のようにします。 + +```js +if ("WebSocketStream" in self) { + // WebSocketStream に対応 +} +``` + +## WebSocketStream オブジェクトの作成 + +WebSocket クライアントを作成するには、まず新しい `WebSocketStream` インスタンスを {{domxref("WebSocketStream.WebSocketStream", "WebSocketStream()")}} コンストラクターで作成する必要があります。最もシンプルな形では、WebSocket サーバーの URL を引数として使用します。 + +```js +const wss = new WebSocketStream("wss://example.com/wss"); +``` + +また、カスタムプロトコルや {{domxref("AbortSignal")}} を含むオプションオブジェクトを受け取ることもできます([接続の切断](#接続の切断)を参照)。 + +```js +const controller = new AbortController(); +const queueWSS = new WebSocketStream("wss://example.com/queue", { + protocols: ["amqp", "mqtt"], + signal: controller.signal, +}); +``` + +## データの送信と受信 + +`WebSocketStream` インスタンスには {{domxref("WebSocketStream.opened", "opened")}} プロパティがあります。これは、WebSocket 接続が正常に開かれると、{{domxref("ReadableStream")}} と {{domxref("WritableStream")}} インスタンスを含むオブジェクトで履行されるプロミスを返します。 + +```js +const { readable, writable } = await wss.opened; +``` + +これらのオブジェクトに対して {{domxref("ReadableStream.getReader", "getReader()")}} と {{domxref("WritableStream.getWriter", "getWriter()")}} を呼び出すと、それぞれ {{domxref("ReadableStreamDefaultReader")}} および {{domxref("WritableStreamDefaultWriter")}} が返されます。これらは、それぞれソケット接続の読み取りと書き込みに使用できます。 + +```js +const reader = readable.getReader(); +const writer = writable.getWriter(); +``` + +ソケットへデータを書き込むには、 {{domxref("WritableStreamDefaultWriter.write()")}} が利用できます。 + +```js +writer.write("My message"); +``` + +ソケットからデータを読み込むには、ストリームが終了するまで、{{domxref("ReadableStreamDefaultReader.read()")}} を継続的に呼び出すことができます。ストリームが終了すると、`done` が `true` になります。 + +```js +while (true) { + const { value, done } = await reader.read(); + if (done) { + break; + } + + // Process value in some way +} +``` + +ブラウザーは必要に際して背圧を適用することで、クライアントがデータを受信および送信する速度を自動的に制御します。クライアントが `read()` できる速度よりも速い速度でデータが到着している場合、基盤となるストリーム API がサーバーに背圧をかけます。さらに、`write()` 操作は安全に行える場合にのみ実行されます。 + +## 接続の切断 + +`WebSocketStream` により、以前に `WebSocket` の {{domxref("WebSocket.close_event", "close")}} および {{domxref("WebSocket.error_event", "error")}} イベントで利用可能だった情報は、{{domxref("WebSocketStream.closed", "closed")}} プロパティで利用できるようになりました。これは、終了コード([`CloseEvent` ステータスコード](/ja/docs/Web/API/CloseEvent/code#値)の完全なリストを参照)とサーバーが接続を終了した理由を示す理由を含むオブジェクトで履行されるプロミスを返します。 + +```js +const { code, reason } = await wss.closed; +``` + +前述の通り、WebSocket 接続は {{domxref("AbortController")}} を使用して終了することができます。必要な {{domxref("AbortSignal")}} は、`WebSocketStream` コンストラクターの作成時に渡され、必要に応じて {{domxref("AbortController.abort()")}} を呼び出すことができます。 + +```js +const controller = new AbortController(); +const wss = new WebSocketStream("wss://example.com/wss", { + signal: controller.signal, +}); + +// しばらく後 + +controller.abort(); +``` + +他に、{{domxref("WebSocketStream.close()")}} メソッドを使用して接続を閉じることもできます。これは主に、カスタムコードや理由を指定したい場合に利用されます。 + +```js +wss.close({ + code: 4000, + reason: "Night draws to a close", +}); +``` + +> [!NOTE] +> 使用するサーバーの設定やステータスコードによっては、サーバーが、終了理由に適した有効なコードを優先して、カスタムコードを無視することがあります。 + +## 完全なサンプルクライアント + +`WebSocketStream` の基本的な使い方を示すために、サンプルクライアントを作成しました。記事の一番下に[全リスト](#全リスト)がありますので、以下の説明と合わせてご覧ください。 + +> [!NOTE] +> この例を動作させるには、サーバーコンポーネントも必要です。[WebSocket サーバーを JavaScript (Deno) で書く](/ja/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_JavaScript_Deno)で説明されている Deno サーバーと連携するようにクライアントを書きましたが、互換性のあるサーバーであればどれでも構いません。 + +デモの HTML は以下の通りです。情報的な [`

`](/ja/docs/Web/HTML/Element/Heading_Elements) と {{htmlelement("p")}} 要素、初期状態では無効になっている WebSocket 接続を閉じるための{{htmlelement("button")}}、および出力メッセージを書き込むための {{htmlelement("div")}} があります。 + +```html +

WebSocketStream Test

+

Sends a ping every five seconds

+ +
+``` + +次に JavaScript です。まず、出力先の `
` と終了タグの ` +
+ + + +``` From 71a80b1fcf3c018dee39e56705c62d14daa8700a Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Sun, 29 Sep 2024 14:55:02 +0900 Subject: [PATCH 2/2] Update index.md --- files/ja/web/api/websockets_api/using_websocketstream/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/files/ja/web/api/websockets_api/using_websocketstream/index.md b/files/ja/web/api/websockets_api/using_websocketstream/index.md index b86bf016acd7f2..da174d6f1585ed 100644 --- a/files/ja/web/api/websockets_api/using_websocketstream/index.md +++ b/files/ja/web/api/websockets_api/using_websocketstream/index.md @@ -193,8 +193,7 @@ async function start() { start(); ``` -> [!NOTE] -> {{domxref("setTimeout")}} 関数は、アプリケーションがストリームを閉じた後に書き込みを行おうとした場合に発生する可能性のあるエラーを処理するために、`write()` 呼び出しを [`try...catch`](/ja/docs/Web/JavaScript/Reference/Statements/try...catch) ブロックで囲みます。 +> **メモ:** {{domxref("setTimeout")}} 関数は、アプリケーションがストリームを閉じた後に書き込みを行おうとした場合に発生する可能性のあるエラーを処理するために、`write()` 呼び出しを [`try...catch`](/ja/docs/Web/JavaScript/Reference/Statements/try...catch) ブロックで囲みます。 WebSocket 接続が閉じられた場合、{{domxref("WebSocketStream.closed", "closed")}} プロミスが履行されることで通知されるように、コードと理由をユーザーに通知するプロミススタイルのコードセクションを追加しました。