htmx Web Socket 擴充功能

Web Sockets 擴充功能可直接從 HTML 輕鬆實現與Web Sockets伺服器的雙向通訊。這取代了先前 htmx 版本中內建的實驗性 hx-ws 屬性。如需從舊版本遷移的協助,請參閱本頁底部的遷移指南。

使用以下屬性設定 WebSockets 的行為

安裝


<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 擴充功能支援兩個設定選項

從 WebSocket 接收訊息

上面的範例建立一個到 /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>

向 WebSocket 發送訊息

在上面的範例中,表單使用 ws-send 屬性來指示,當表單被提交時,表單值應序列化為 JSON 並發送到最近的封閉 WebSocket,在本例中為 /chatroom 端點。

序列化的值將包含一個欄位 HEADERS,其中包含通常與 htmx 請求一起提交的標頭。

自動重新連線

如果 WebSocket 因 Abnormal ClosureService RestartTry 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 端點時,會觸發此事件。

詳細資訊

事件 - htmx:wsOpen

當已建立與 WebSocket 端點的連線時,會觸發此事件。

詳細資訊

事件 - htmx:wsClose

當與 WebSocket 端點的連線正常關閉時,會觸發此事件。您可以透過檢查 detail.event 屬性來檢查事件是否是由錯誤引起的。

詳細資訊

事件 - htmx:wsError

當 socket 上引發 onerror 事件時,會觸發此事件。

詳細資訊

事件 - htmx:wsBeforeMessage

當 socket 剛接收到訊息時,會觸發此事件,類似於 htmx:beforeOnLoad。此事件會在發生任何處理之前觸發。

如果取消事件,則不會進行任何進一步的處理。

事件 - htmx:wsAfterMessage

當 htmx 完全處理完訊息且所有變更都已完成時,會觸發此事件,類似於 htmx:afterOnLoad

取消此事件沒有任何作用。

事件 - htmx:wsConfigSend

當準備從 ws-send 元素發送訊息時,會觸發此事件。與 htmx:configRequest 類似,它允許您在發送前修改訊息。

如果取消事件,則不會進行任何進一步的處理,並且不會發送任何訊息。

詳細資訊

事件 - htmx:wsBeforeSend

在發送訊息之前立即觸發此事件。這包括來自佇列的訊息。此時無法修改訊息。

如果取消事件,則該訊息將從佇列中丟棄且不會發送。

詳細資訊

事件 - htmx:wsAfterSend

在發送訊息之後立即觸發此事件。這包括來自佇列的訊息。

取消此事件沒有任何作用。

詳細資訊

Socket 包裝器

您可能會注意到所有事件都公開了 detail.socketWrapper 屬性。此包裝器保存 socket 物件本身和訊息佇列。它還封裝了重新連線演算法。它公開了幾個成員

此包裝器可用於您的事件處理常式中,以監控和操作佇列(例如,您可以在重新連線時重設佇列),並發送其他訊息(例如,如果您想分批發送資料)。fromElt 參數是可選的,如果指定,將從指定的元素觸發對應的 websocket 事件,即發送您的訊息時的 htmx:wsBeforeSendhtmx: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 伺服器的任何子表單