サーバー送信イベント
拡張機能は、HTML から直接 EventSource に接続します。Web サーバーへの接続を管理し、サーバーイベントをリッスンし、そのコンテンツをリアルタイムで htmx ウェブページに置き換えます。
SSE は、既存の HTTP 接続を介して動作する軽量な WebSockets の代替手段であるため、プロキシサーバーやファイアウォールを介して簡単に使用できます。SSE は一方向サービスであるため、接続が確立された後、SSE サーバーにメッセージを送信することはできません。双方向通信が必要な場合は、代わりに WebSockets を検討してください。
この拡張機能は、以前のバージョンの htmx に組み込まれていた実験的な hx-sse
属性に取って代わります。以前のバージョンからの移行に関するヘルプについては、このページの下部にある移行ガイドを参照してください。
以下の属性を使用して、SSE 接続の動作を構成します。
sse-connect="<url>"
- SSE サーバーのURL。sse-swap="<message-name>"
- DOM に置き換えるメッセージの名前。hx-trigger="sse:<message-name>"
- SSE メッセージは、hx-trigger
属性を使用して HTTP コールバックをトリガーすることもできます。sse-close=<message-name>
- そのメッセージを受信したときに EventStream を正常に閉じます。クライアントに最終的に停止する情報を送信する場合に役立つ場合があります。
<script src="https://unpkg.com/htmx-ext-sse@2.2.2/sse.js"></script>
<div hx-ext="sse" sse-connect="/chatroom" sse-swap="message">
Contents of this box will be updated in real time
with every SSE message received from the chatroom.
</div>
SSE サーバーに接続するには、hx-ext="sse"
属性を使用してその HTML 要素に拡張機能をインストールし、sse-connect="<url>"
を要素に追加して接続します。
サーバーアプリケーションを設計する際には、SSE は HTTP リクエストとまったく同じように動作することに注意してください。接続を確立した後、サーバーにメッセージを送信することはできませんが、リクエストとともにパラメーターをサーバーに送信できます。そのため、https://my-server/chat-updates
でサーバーへの SSE 接続を行う代わりに、https://my-server/chat-updates?friends=true&format=detailed
に接続することもできます。これにより、サーバーはクライアントのニーズに合わせてレスポンスをカスタマイズできます。
SSE メッセージは、イベント名とデータパケットで構成されます。メッセージには他のメタデータは許可されません。例を以下に示します。
event: EventName
data: <div>Content to swap into your HTML page.</div>
sse-swap
属性を使用してこのイベントをリッスンし、そのコンテンツをウェブページに置き換えます。
<div hx-ext="sse" sse-connect="/event-source" sse-swap="EventName"></div>
サーバーのメッセージのEventName
という名前は、sse-swap
属性の値と一致する必要があることに注意してください。サーバーは必要な数の異なるイベント名を使用できますが、注意が必要です。ブラウザは、明示的に名前が付けられたイベントのみをリッスンできます。したがって、サーバーがChatroomUpdate
という名前のイベントを送信しても、ブラウザがChatUpdate
という名前のイベントのみをリッスンしている場合、余分なイベントは破棄されます。
SSE メッセージは、イベント名なしで送信することもできます。この場合、ブラウザはその代わりにデフォルト名message
を使用します。上記で指定された同じルールが適用されます。サーバーが名前のないメッセージを送信する場合は、sse-swap="message"
を含めることでリッスンする必要があります。キャッチオール名を使用するオプションはありません。これは次のようになります。
data: <div>Content to swap into your HTML page.</div>
<div hx-ext="sse" sse-connect="/event-source" sse-swap="message"></div>
単一の EventSource から複数のイベント(名前付きまたは名前なし)をリッスンすることもできます。リスナーは、1)hx-ext
およびsse-connect
属性を含む要素と同じ要素、または2)hx-ext
およびsse-connect
属性を含む要素の子要素のいずれかでなければなりません。
Multiple events in the same element
<div hx-ext="sse" sse-connect="/server-url" sse-swap="event1,event2"></div>
Multiple events in different elements (from the same source).
<div hx-ext="sse" sse-connect="/server-url">
<div sse-swap="event1"></div>
<div sse-swap="event2"></div>
</div>
サーバー送信イベントの接続が確立されると、子要素は特別なhx-trigger
構文sse:<event_name>
を使用してこれらのイベントをリッスンできます。これは、hx-get
などとの組み合わせで、要素にリクエストをトリガーさせます。
例を以下に示します。
<div hx-ext="sse" sse-connect="/event_stream">
<div hx-get="/chatroom" hx-trigger="sse:chatter">
...
</div>
</div>
この例では、event_stream
エンドポイントへのSSE接続を確立し、chatter
イベントが表示されるたびに/chatroom
URLへのGET
をトリガーします。
SSE Event Streamが予期せず閉じられた場合、ブラウザは自動的に再接続を試みる必要があります。ただし、まれにこれは機能せず、ブラウザがハングする可能性があります。この拡張機能は、ブラウザの自動再接続の上に独自の再接続ロジック(指数バックオフアルゴリズムを使用)を追加するため、SSEストリームは常に可能な限り信頼できるものになります。
Htmxには、Node.jsで記述されたデモSSEサーバーが含まれており、SSEの動作を確認し、独自のSSEコードのブートストラップを開始するのに役立ちます。htmx配布の/test/ws-sseフォルダーにあります。/test/ws-sse/README.mdで、テストサーバーの実行と使用に関する手順を確認してください。
以前のバージョンのhtmxは、組み込みタグhx-sse
を使用してサーバー送信イベントを実装していました。このコードは拡張機能に移行されました。このバージョンに移行するために必要な手順を以下に示します。
古い属性 | 新しい属性 | コメント |
---|---|---|
hx-sse="" | hx-ext="sse" | hx-ext="sse" 属性を使用して、任意のHTML要素にSSE拡張機能をインストールします。 |
hx-sse="connect:<url>" | sse-connect="<url>" | Event StreamのURLを指定する新しい属性sse-connect をタグに追加します。この属性は、hx-ext 属性と同じタグになければなりません。 |
hx-sse="swap:<EventName>" | sse-swap="<EventName>" | SSE拡張機能を介して交換される要素に新しい属性sse-swap を追加します。この属性は、hx-ext 属性を含むタグの**上**または**内**に配置する必要があります。 |
hx-trigger="sse:<EventName>" | 変更なし | hx-trigger 属性は変更する必要はありません。拡張機能はこれらの属性を識別し、sse: で始まるイベントのリスナーを追加します。 |
この拡張機能はいくつかのイベントをディスパッチします。これらのイベントは次のようにリッスンできます。
document.body.addEventListener('htmx:sseBeforeMessage', function (e) {
// do something before the event data is swapped in
})
各イベントオブジェクトには、イベントの詳細を含むdetail
フィールドがあります。
htmx:sseOpen
このイベントは、SSE接続が正常に確立されたときにディスパッチされます。
detail.elt
- SSE接続が設定された要素。これはsse-connect
属性を持つ要素です。detail.source
- EventSourceオブジェクト。htmx:sseError
このイベントは、SSE接続を確立できなかったときにディスパッチされます。
detail.error
- EventSourceの作成中に発生したエラー。detail.source
- EventSourceオブジェクト。htmx:sseBeforeMessage
このイベントは、SSEイベントデータがDOMにスワップされる直前にディスパッチされます。スワップしたくない場合は、イベントでpreventDefault()
を呼び出します。さらに、detail
フィールドはMessageEventです。これは、SSEメッセージを受信したときにEventSourceによって作成されたイベントです。
detail.elt
- スワップターゲット。htmx:sseMessage
このイベントは、SSEイベントデータがDOMにスワップされた後にディスパッチされます。detail
フィールドはMessageEventです。これは、SSEメッセージを受信したときにEventSourceによって作成されたイベントです。
htmx:sseClose
このイベントは、3つの異なるクローズシナリオでディスパッチされます。シナリオを制御するために、ユーザーはevt.detail.ssecloseプロパティを制御できます。
document.body.addEventListener('htmx:sseClose', function (e) {
const reason = e.detail.type
switch (reason) {
case "nodeMissing":
// Parent node is missing and therefore connection was closed
...
case "nodeReplaced":
// Parent node replacement caused closing of connection
...
case "message":
// connection was closed due to reception of message sse-close
...
}
})
detail.elt
- スワップターゲット。