Web Sockets 擴充功能可直接從 HTML 輕鬆實現與Web Sockets伺服器的雙向通訊。這取代了先前 htmx 版本中內建的實驗性 hx-ws
屬性。如需從舊版本遷移的協助,請參閱本頁底部的遷移指南。
使用以下屬性設定 WebSockets 的行為
ws-connect="<url>"
或 ws-connect="<prefix>:<url>"
- 用於建立 WebSocket
連線的 URL。ws
或 wss
。如果未指定,HTMX 預設會將位置的 scheme-type、主機和埠新增,以讓瀏覽器透過 websockets 發送 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>
WebSockets 擴充功能支援兩個設定選項
createWebSocket
- 可用於建立自訂 WebSocket 實例的工廠函式。必須是一個函式,返回 WebSocket
物件wsBinaryType
- 一個字串值,定義 socket 的 binaryType
屬性。預設值為 blob
上面的範例建立一個到 /chatroom
端點的 WebSocket。從 websocket 發送下來的內容會被解析為 HTML,並透過 id
屬性交換,使用與 Out of Band Swaps 相同的邏輯。
因此,如果您想變更交換方法(例如,在元素的結尾附加內容或將交換委派給擴充功能),您需要在伺服器發送的訊息正文中指定。
<!-- 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
端點。
序列化的值將包含一個欄位 HEADERS
,其中包含通常與 htmx 請求一起提交的標頭。
如果 WebSocket 因 Abnormal Closure
、Service Restart
或 Try Again Later
而意外關閉,此擴充功能將嘗試重新連線,直到重新建立連線為止。
預設情況下,此擴充功能使用全抖動指數退避演算法,該演算法會選擇一個隨機的重試延遲,該延遲會隨著時間呈指數增長。您可以透過將其寫入 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
}
此擴充功能還實作了一個簡單的佇列機制,當 socket 不處於 OPEN
狀態時,該機制將訊息保留在記憶體中,並在連線恢復後發送這些訊息。
WebSockets 擴充功能公開一組事件,允許您觀察和自訂其行為。
htmx:wsConnecting
當嘗試連線到 WebSocket 端點時,會觸發此事件。
detail.event.type
- 事件的類型 ('connecting'
)htmx:wsOpen
當已建立與 WebSocket 端點的連線時,會觸發此事件。
detail.elt
- 保留 socket 的元素(具有 ws-connect
屬性的元素)detail.event
- 來自 socket 的原始事件detail.socketWrapper
- socket 物件的包裝器htmx:wsClose
當與 WebSocket 端點的連線正常關閉時,會觸發此事件。您可以透過檢查 detail.event
屬性來檢查事件是否是由錯誤引起的。
detail.elt
- 保留 socket 的元素(具有 ws-connect
屬性的元素)detail.event
- 來自 socket 的原始事件detail.socketWrapper
- socket 物件的包裝器htmx:wsError
當 socket 上引發 onerror
事件時,會觸發此事件。
detail.elt
- 保留 socket 的元素(具有 ws-connect
屬性的元素)detail.error
- 錯誤物件detail.socketWrapper
- socket 物件的包裝器htmx:wsBeforeMessage
當 socket 剛接收到訊息時,會觸發此事件,類似於 htmx:beforeOnLoad
。此事件會在發生任何處理之前觸發。
如果取消事件,則不會進行任何進一步的處理。
detail.elt
- 保留 socket 的元素(具有 ws-connect
屬性的元素)detail.message
- 原始訊息內容detail.socketWrapper
- socket 物件的包裝器htmx:wsAfterMessage
當 htmx 完全處理完訊息且所有變更都已完成時,會觸發此事件,類似於 htmx:afterOnLoad
。
取消此事件沒有任何作用。
detail.elt
- 保留 socket 的元素(具有 ws-connect
屬性的元素)detail.message
- 原始訊息內容detail.socketWrapper
- socket 物件的包裝器htmx:wsConfigSend
當準備從 ws-send
元素發送訊息時,會觸發此事件。與 htmx:configRequest
類似,它允許您在發送前修改訊息。
如果取消事件,則不會進行任何進一步的處理,並且不會發送任何訊息。
detail.parameters
- 將在請求中提交的參數detail.unfilteredParameters
- 在被 hx-select
過濾之前找到的參數detail.headers
- 請求標頭。如果不是 falsy,則會附加到 HEADERS
屬性中的 bodydetail.errors
- 驗證錯誤。如果非空,將阻止發送並觸發 htmx:validation:halted
事件detail.triggeringEvent
- 觸發發送的事件detail.messageBody
- 將發送到 socket 的原始訊息 body。未定義,可以設定為 WebSockets 支援的任何類型的值。如果設定,將覆寫預設的 JSON 序列化。如果您想使用其他格式(例如 XML 或 MessagePack),這很有用detail.elt
- 發送發送的元素(具有 ws-send
屬性的元素)detail.socketWrapper
- socket 物件的包裝器htmx:wsBeforeSend
在發送訊息之前立即觸發此事件。這包括來自佇列的訊息。此時無法修改訊息。
如果取消事件,則該訊息將從佇列中丟棄且不會發送。
detail.elt
- 發送請求的元素(具有 ws-connect
屬性的元素)detail.message
- 原始訊息內容detail.socketWrapper
- socket 物件的包裝器htmx:wsAfterSend
在發送訊息之後立即觸發此事件。這包括來自佇列的訊息。
取消此事件沒有任何作用。
detail.elt
- 發送請求的元素(具有 ws-connect
屬性的元素)detail.message
- 原始訊息內容detail.socketWrapper
- socket 物件的包裝器您可能會注意到所有事件都公開了 detail.socketWrapper
屬性。此包裝器保存 socket 物件本身和訊息佇列。它還封裝了重新連線演算法。它公開了幾個成員
send(message, fromElt)
- 安全地發送訊息。如果 socket 未開啟,則該訊息將改為保存在佇列中,並在 socket 準備好時發送。sendImmediately(message, fromElt)
- 嘗試發送訊息,無論 socket 狀態如何,都會繞過佇列。可能會失敗queue
- 佇列中等待的訊息陣列。此包裝器可用於您的事件處理常式中,以監控和操作佇列(例如,您可以在重新連線時重設佇列),並發送其他訊息(例如,如果您想分批發送資料)。fromElt
參數是可選的,如果指定,將從指定的元素觸發對應的 websocket 事件,即發送您的訊息時的 htmx:wsBeforeSend
和 htmx:wsAfterSend
事件。
Htmx 包含一個以 Node.js 編寫的示範 WebSockets 伺服器,可協助您查看 WebSockets 的運作方式,並開始引導您自己的 WebSockets 程式碼。它位於 htmx 發行版本的 /test/ws-sse 資料夾中。請查看 /test/ws-sse/README.md,以取得有關執行和使用測試伺服器的說明。
先前版本的 htmx 使用內建標籤 hx-ws
來實作 WebSockets。此程式碼已遷移到擴充功能中。以下是您需要採取的步驟,才能遷移到此版本
舊屬性 | 新屬性 | 註解 |
---|---|---|
hx-ws="" | hx-ext="ws" | 使用 hx-ext="ws" 屬性將 WebSockets 擴充功能安裝到任何 HTML 元素中。 |
hx-ws="connect:<url>" | ws-connect="<url>" | 將新屬性 ws-connect 新增到定義擴充功能的標籤,以指定您使用的 WebSockets 伺服器的 URL。 |
hx-ws="send" | ws-send="" | 新增新屬性 ws-send 以標記應將資料發送到 WebSocket 伺服器的任何子表單 |