htmx WebSocket 扩展

WebSocket 扩展允许直接从 HTML 与 WebSocket 服务器进行简单、双向通信。这取代了之前 htmx 版本中内置的实验性 hx-ws 属性。有关从旧版本迁移的帮助,请参阅本页底部的 迁移 指南。

使用以下属性配置 WebSocket 的行为

安装


<script src="https://unpkg.com/[email protected]/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 扩展支持两种配置选项

接收来自 WebSocket 的消息

上面的示例建立了与 /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>

向 WebSocket 发送消息

在上面的示例中,表单使用 ws-send 属性来指示当表单提交时,表单值应序列化为 JSON 并发送到最近的封闭 WebSocket,在本例中为 /chatroom 端点。

序列化值将包含一个名为 HEADERS 的字段,其中包含通常与 htmx 请求一起提交的标头。

自动重连

如果 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 端点时触发此事件。

详细信息

事件 - htmx:wsOpen

当与 WebSocket 端点的连接建立时触发此事件。

详细信息

事件 - htmx:wsClose

当与 WebSocket 端点的连接正常关闭时触发此事件。您可以检查 detail.event 属性以确定事件是否是由错误引起的。

详细信息

事件 - htmx:wsError

当套接字上触发 onerror 事件时触发此事件。

详细信息

事件 - htmx:wsBeforeMessage

当套接字接收到消息时触发此事件,类似于 htmx:beforeOnLoad。此事件在任何处理发生之前触发。

如果事件被取消,则不会进行进一步的处理。

事件 - htmx:wsAfterMessage

当 htmx 完全处理完消息并且所有更改都已解决时触发此事件,类似于 htmx:afterOnLoad

取消此事件不会产生任何影响。

事件 - htmx:wsConfigSend

当准备从 ws-send 元素发送消息时触发此事件。类似于 htmx:configRequest,它允许您在发送之前修改消息。

如果事件被取消,则不会进行进一步的处理,也不会发送任何消息。

详细信息

事件 - htmx:wsBeforeSend

在发送消息之前触发此事件。这包括来自队列的消息。此时无法修改消息。

如果事件被取消,则消息将从队列中丢弃,不会发送。

详细信息

事件 - htmx:wsAfterSend

在发送消息后触发此事件。这包括来自队列的消息。

取消事件不会产生任何影响。

详细信息

套接字包装器

您可能会注意到所有事件都公开 detail.socketWrapper 属性。此包装器保存套接字对象本身和消息队列。它还封装了重新连接算法。它公开了一些成员

此包装器可以在您的事件处理程序中使用,用于监控和操作队列(例如,您可以在重新连接时重置队列),以及发送其他消息(例如,如果您想分批发送数据)。fromElt 参数是可选的,如果指定,将在发送您的消息时从指定的元素触发相应的 WebSocket 事件,即 htmx:wsBeforeSendhtmx:wsAfterSend 事件。

使用演示服务器进行测试

Htmx 包含一个用 Node.js 编写的演示 WebSocket 服务器,它可以帮助您了解 WebSocket 的工作原理,并开始引导自己的 WebSocket 代码。它位于 htmx 发行版的 /test/ws-sse 文件夹中。查看 /test/ws-sse/README.md 以了解有关运行和使用测试服务器的说明。

从旧版本迁移

旧版本的 htmx 使用内置标签 hx-ws 来实现 WebSocket。此代码已迁移到扩展中。以下是如何迁移到此版本的步骤

旧属性新属性注释
hx-ws=""hx-ext="ws"使用 hx-ext="ws" 属性将 WebSocket 扩展安装到任何 HTML 元素中。
hx-ws="connect:<url>"ws-connect="<url>"在定义扩展的标签中添加一个新属性 ws-connect,以指定您正在使用的 WebSocket 服务器的 URL。
hx-ws="send"ws-send=""添加一个新属性 ws-send 来标记应将数据发送到 WebSocket 服务器的任何子表单