WebSocket 扩展允许直接从 HTML 与 WebSocket 服务器进行简单、双向通信。这取代了之前 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/[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 扩展支持两种配置选项
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
端点。
序列化值将包含一个名为 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 端点时触发此事件。
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 完全处理完消息并且所有更改都已解决时触发此事件,类似于 htmx:afterOnLoad
。
取消此事件不会产生任何影响。
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 支持的任何类型的值。如果设置,将覆盖默认的 JSON 序列化。如果您想要使用其他格式,例如 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 使用内置标签 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 服务器的任何子表单 |