Web Socket 拡張機能により、HTML から直接 Web Socket サーバーとの容易な双方向通信が可能になります。これは、以前のバージョンの htmx に組み込まれていた実験的な hx-ws
属性に取って代わるものです。旧バージョンからの移行については、このページ下部の移行ガイドを参照してください。
以下の属性を使用して、WebSocket の動作を構成します。
ws-connect="<url>"
または ws-connect="<prefix>:<url>"
- WebSocket
接続を確立する URL。ws
または wss
をオプションで指定できます。指定しない場合、HTMX はデフォルトで、ロケーションのスキームタイプ、ホスト、ポートを追加して、ブラウザが Websocket 経由で Cookie を送信するようにします。ws-send
- 要素のトリガー値(自然なイベントまたは[hx-trigger
]で指定されたイベントのいずれか)に基づいて、最も近い websocket にメッセージを送信します。
<script src="https://unpkg.com/htmx-ext-ws@2.0.1/ws.js"></script>
<div hx-ext="ws" ws-connect="/chatroom">
<div id="notifications"></div>
<div id="chat_room">
...
</div>
<form id="form" ws-send>
<input name="chat_message">
</form>
</div>
WebSocket 拡張機能は、2 つの設定オプションをサポートしています。
createWebSocket
- カスタム WebSocket インスタンスを作成するために使用できるファクトリ関数。関数でなければならず、WebSocket
オブジェクトを返します。wsBinaryType
- ソケットの binaryType
プロパティを定義する文字列値。デフォルト値は blob
です。上記の例では、/chatroom
エンドポイントに WebSocket を確立しています。websocket から送信されたコンテンツは HTML として解析され、アウトオブバンド交換 と同じロジックを使用して、id
プロパティで置換されます。
そのため、交換方法を変更する場合(例:要素の最後にコンテンツを追加する、または拡張機能に交換を委任する)、サーバーから送信されるメッセージ本文でそれを指定する必要があります。
<!-- will be interpreted as hx-swap-oob="true" by default -->
<form id="form">
...
</form>
<!-- will be appended to #notifications div -->
<div id="notifications" hx-swap-oob="beforeend">
New message received
</div>
<!-- will be swapped using an extension -->
<div id="chat_room" hx-swap-oob="morphdom">
....
</div>
上記の例では、フォームは ws-send
属性を使用して、送信されたときにフォームの値を **JSON としてシリアル化し**、最も近い WebSocket
(この場合は /chatroom
エンドポイント)に送信することを示しています。
シリアル化された値には、通常 htmx リクエストで送信されるヘッダーが含まれる HEADERS
フィールドが含まれます。
Abnormal Closure
、Service Restart
、Try Again Later
などにより、WebSocket が予期せず閉じられた場合、この拡張機能は接続が再確立されるまで再接続を試みます。
デフォルトでは、この拡張機能は完全ジッタ付きの 指数バックオフアルゴリズム を使用し、時間とともに指数関数的に増加するランダムな再試行遅延を選択します。htmx.config.wsReconnectDelay
に記述することで、別のアルゴリズムを使用できます。この関数は、再試行回数という単一のパラメータを取り、再試行するまでの待機時間(ミリ秒単位)を返します。
// example reconnect delay that you shouldn't use because
// it's not as good as the algorithm that's already in place
htmx.config.wsReconnectDelay = function (retryCount) {
return retryCount * 1000 // return value in milliseconds
}
この拡張機能は、ソケットが OPEN
状態ではない場合にメッセージをメモリに保持し、接続が復元されると送信する、単純なキューイングメカニズムも実装しています。
WebSocket 拡張機能は、その動作を観察およびカスタマイズできる一連のイベントを公開します。
htmx:wsConnecting
WebSocket エンドポイントへの接続を試行しているときにトリガーされます。
detail.event.type
- イベントのタイプ('connecting'
)htmx:wsOpen
WebSocket エンドポイントへの接続が確立されたときにトリガーされます。
detail.elt
- ソケットを保持する要素(ws-connect
属性を持つ要素)detail.event
- ソケットからの元のイベントdetail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsClose
WebSocket エンドポイントへの接続が正常に閉じられたときにトリガーされます。detail.event
プロパティを検査することで、イベントがエラーによって発生したかどうかを確認できます。
detail.elt
- ソケットを保持する要素(ws-connect
属性を持つ要素)detail.event
- ソケットからの元のイベントdetail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsError
ソケットの onerror
イベントが発生したときにトリガーされます。
detail.elt
- ソケットを保持する要素(ws-connect
属性を持つ要素)detail.error
- エラーオブジェクトdetail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsBeforeMessage
htmx:beforeOnLoad
と同様に、ソケットによってメッセージが受信された直後にトリガーされます。このイベントは、処理が行われる前に発生します。
イベントがキャンセルされると、それ以上の処理は行われません。
detail.elt
- ソケットを保持する要素(ws-connect
属性を持つ要素)detail.message
- 生のメッセージコンテンツdetail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsAfterMessage
htmx:afterOnLoad
と同様に、htmx によってメッセージが完全に処理され、すべての変更が完了したときにトリガーされます。
このイベントをキャンセルしても影響はありません。
detail.elt
- ソケットを保持する要素(ws-connect
属性を持つ要素)detail.message
- 生のメッセージコンテンツdetail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsConfigSend
ws-send
要素からメッセージを送信する準備をしているときにトリガーされます。htmx:configRequest
と同様に、送信前にメッセージを変更できます。
イベントがキャンセルされると、それ以上の処理は行われず、メッセージは送信されません。
detail.parameters
- リクエストで送信されるパラメータdetail.unfilteredParameters
- hx-select
によるフィルタリングの前に検出されたパラメータdetail.headers
- リクエストヘッダー。偽ではない場合、HEADERS
プロパティに本文に添付されます。detail.errors
- 検証エラー。空でない場合、送信を防止し、htmx:validation:halted
イベントをトリガーします。detail.triggeringEvent
- 送信をトリガーしたイベントdetail.messageBody
- ソケットに送信される生のメッセージ本文。未定義で、WebSocket でサポートされている任意の型の値に設定できます。XML や MessagePack など、他の形式を使用したい場合に役立ちます。detail.elt
- 送信をディスパッチした要素(ws-send
属性を持つ要素)detail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsBeforeSend
メッセージを送信する直前にトリガーされます。これには、キューからのメッセージも含まれます。この時点ではメッセージを変更できません。
イベントがキャンセルされると、メッセージはキューから破棄され、送信されません。
detail.elt
- リクエストをディスパッチした要素(ws-connect
属性を持つ要素)detail.message
- 生のメッセージコンテンツdetail.socketWrapper
- ソケットオブジェクトのラッパーhtmx:wsAfterSend
メッセージを送信した直後にトリガーされます。これには、キューからのメッセージも含まれます。
イベントをキャンセルしても影響はありません。
detail.elt
- リクエストをディスパッチした要素(ws-connect
属性を持つ要素)detail.message
- 生のメッセージコンテンツdetail.socketWrapper
- ソケットオブジェクトのラッパーすべてのイベントが detail.socketWrapper
プロパティを公開していることに気付くかもしれません。このラッパーは、ソケットオブジェクト自体とメッセージキューを保持します。また、再接続アルゴリズムもカプセル化します。いくつかのメンバーを公開しています。
send(message, fromElt)
- 安全にメッセージを送信します。ソケットが開いていない場合、代わりにメッセージはキューに保持され、ソケットの準備ができると送信されます。sendImmediately(message, fromElt)
- ソケットの状態に関係なくメッセージの送信を試み、キューをバイパスします。失敗する可能性があります。queue
- キューで待機しているメッセージの配列。このラッパーは、イベントハンドラーで使用してキューを監視および操作し(例:再接続時にキューをリセットする)、追加のメッセージを送信するために使用できます(例:データをバッチで送信する場合)。fromElt
パラメータはオプションで、指定されている場合、指定された要素から対応する websocket イベント、つまりメッセージを送信するときに htmx:wsBeforeSend
および htmx:wsAfterSend
イベントをトリガーします。
Htmx には、Node.js で記述されたデモ WebSocket サーバーが含まれており、WebSocket の動作を確認し、独自の WebSocket コードのブートストラップを開始するのに役立ちます。これは、htmx 配布の /test/ws-sse フォルダーにあります。テストサーバーの実行と使用方法については、/test/ws-sse/README.md を参照してください。
以前のバージョンの htmx は、WebSocket を実装するために組み込みタグ hx-ws
を使用していました。このコードは、代わりに拡張機能に移行されました。このバージョンに移行するために必要な手順を次に示します。
古い属性 | 新しい属性 | コメント |
---|---|---|
hx-ws="" | hx-ext="ws" | hx-ext="ws" 属性を使用して、任意の HTML 要素に WebSocket 拡張機能をインストールします。 |
hx-ws="connect:<url>" | ws-connect="<url>" | 使用している WebSocket サーバーの URL を指定するために、拡張機能を定義するタグに新しい属性 ws-connect を追加します。 |
hx-ws="send" | ws-send="" | WebSocket サーバーにデータを送信する必要がある子フォームをマークするために、新しい属性 ws-send を追加します。 |