htmx: 服务器发送事件 (SSE) 扩展
htmx: Server Sent Event (SSE) Extension

原始链接: https://htmx.org/extensions/sse/

## htmx Server-Sent Events (SSE) 扩展总结 htmx-ext-sse 扩展通过连接到服务器发送事件 (SSE) 流,实现网页的实时更新。SSE 是 WebSockets 的一种轻量级替代方案,通过标准的 HTTP 连接运行 – 使其防火墙友好。与 WebSockets 不同,SSE 是**单向的**(仅服务器到客户端)。 **主要特性与属性:** * **`hx-ext="sse"`**: 在 HTML 元素上启用扩展。 * **`sse-connect=""`**: 指定 SSE 服务器的 URL。 * **`sse-swap=""`**: 定义哪个服务器消息更新元素的内容。 * **`hx-trigger="sse:"`**: 基于 SSE 消息触发 HTTP 回调。 * **`sse-close=`**: 收到特定消息时,优雅地关闭连接。 **安装:** 可以通过 CDN 或 npm 轻松添加,确保在加载扩展*之前*加载 `htmx.org`。 **接收事件:** SSE 消息包括事件名称和数据。使用 `sse-swap="message"` 处理未命名的事件,并使 `sse-swap` 值与服务器的事件名称匹配以处理命名的事件。 可以在同一元素或子元素上监听多个事件。 该扩展还包括自动重连逻辑以提高可靠性,并分发自定义事件以进行生命周期管理(连接打开、错误、消息、关闭)。 提供了一个演示服务器用于测试。 此扩展取代了旧的 `hx-sse` 属性,现有用户需要迁移。

## htmx SSE 扩展与讨论总结 一个新的 htmx 服务器发送事件 (SSE) 扩展正在讨论中,但很快将集成到核心库中,随下一次发布 (v4) 一起提供。这允许服务器向客户端流式传输更新,而无需完全页面重新加载,从而简化后端开发和测试。 评论者赞赏 htmx 在无需复杂前端框架的情况下处理许多用例的能力,这符合“渐进式复杂性”的概念。一些用户还探索了类似 DataStar 的库,该库已经包含 SSE 支持,并提供轻量级的客户端交互原语。 讨论要点包括将 SSE 与传统的 EventSource 和 WebSockets 进行比较,以及强调 htmx 的功能超越简单的 `innerHTML` 替换。有人担心增加的复杂性可能会影响重视 htmx 简单性的用户,并提出了一个功能请求,即更容易在 hx- 属性中解析 JSON 数据。
相关文章

原文

The Server Sent Events extension connects to an EventSource directly from HTML. It manages the connections to your web server, listens for server events, and then swaps their contents into your htmx webpage in real-time.

SSE is a lightweight alternative to WebSockets that works over existing HTTP connections, so it is easy to use through proxy servers and firewalls. Remember, SSE is a uni-directional service, so you cannot send any messages to an SSE server once the connection has been established. If you need bi-directional communication, then you should consider using WebSockets instead.

This extension replaces the experimental hx-sse attribute built into previous versions of htmx. For help migrating from older versions, see the migration guide at the bottom of this page.

Use the following attributes to configure how SSE connections behave:

  • sse-connect="<url>" - The URL of the SSE server.
  • sse-swap="<message-name>" - The name of the message to swap into the DOM.
  • hx-trigger="sse:<message-name>" - SSE messages can also trigger HTTP callbacks using the hx-trigger attribute.
  • sse-close=<message-name> - To close the EventStream gracefully when that message is received. This might be helpful if you want to send information to a client that will eventually stop.

Installing

The fastest way to install sse is to load it via a CDN. Remember to always include the core htmx library before the extension and enable the extension.

<head>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.min.js" integrity="sha384-/TgkGk7p307TH7EXJDuUlgG3Ce1UVolAOFopFekQkkXihi5u/6OCvVKyz1W+idaz" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]" integrity="sha384-A986SAtodyH8eg8x8irJnYUk7i9inVQqYigD6qZ9evobksGNIXfeFvDwLSHcp31N" crossorigin="anonymous"></script>
</head>
<body hx-ext="sse">

An unminified version is also available at https://cdn.jsdelivr.net/npm/htmx-ext-sse/dist/sse.js.

While the CDN approach is simple, you may want to consider not using CDNs in production. The next easiest way to install sse is to simply copy it into your project. Download the extension from https://cdn.jsdelivr.net/npm/htmx-ext-sse, add it to the appropriate directory in your project and include it where necessary with a <script> tag.

For npm-style build systems, you can install sse via npm:

npm install htmx-ext-sse

After installing, you’ll need to use appropriate tooling to bundle node_modules/htmx-ext-sse/dist/sse.js (or .min.js). For example, you might bundle the extension with htmx core from node_modules/htmx.org/dist/htmx.js and project-specific code.

If you are using a bundler to manage your javascript (e.g. Webpack, Rollup):

  • Install htmx.org and htmx-ext-sse via npm
  • Import both packages to your index.js
import `htmx.org`;
import `htmx-ext-sse`; 

Usage


<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>

Connecting to an SSE Server

To connect to an SSE server, use the hx-ext="sse" attribute to install the extension on that HTML element, then add sse-connect="<url>" to the element to make the connection.

When designing your server application, remember that SSE works just like any HTTP request. Although you cannot send any messages to the server after you have established a connection, you can send parameters to the server along with your request. So, instead of making an SSE connection to your server at https://my-server/chat-updates you can also connect to https://my-server/chat-updates?friends=true&format=detailed. This allows your server to customize its responses to what your client needs.

Receiving Named Events

SSE messages consist of an event name and a data packet. No other metadata is allowed in the message. Here is an example:

event: EventName
data: <div>Content to swap into your HTML page.</div>

We’ll use the sse-swap attribute to listen for this event and swap its contents into our webpage.


<div hx-ext="sse" sse-connect="/event-source" sse-swap="EventName"></div>

Notice that the name EventName from the server’s message must match the value in the sse-swap attribute. Your server can use as many different event names as necessary, but be careful: browsers can only listen for events that have been explicitly named. So, if your server sends an event named ChatroomUpdate but your browser is only listening for events named ChatUpdate then the extra event will be discarded.

Receiving Unnamed Events

SSE messages can also be sent without any event name. In this case, the browser uses the default name message in its place. The same rules specified above still apply. If your server sends an unnamed message, then you must listen for it by including sse-swap="message". There is no option for using a catch-all name. Here’s how this looks:

data: <div>Content to swap into your HTML page.</div>

<div hx-ext="sse" sse-connect="/event-source" sse-swap="message"></div>

Receiving Multiple Events

You can also listen to multiple events (named or unnamed) from a single EventSource. Listeners must be either 1) the same element that contains the hx-ext and sse-connect attributes, or 2) child elements of the element containing the hx-ext and sse-connect attributes.


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>

Trigger Server Callbacks

When a connection for server sent events has been established, child elements can listen for these events by using the special hx-trigger syntax sse:<event_name>. This, when combined with an hx-get or similar will trigger the element to make a request.

Here is an example:


<div hx-ext="sse" sse-connect="/event_stream">
    <div hx-get="/chatroom" hx-trigger="sse:chatter">
        ...
    </div>
</div>

This example establishes an SSE connection to the event_stream end point which then triggers a GET to the /chatroom url whenever the chatter event is seen.

Automatic Reconnection

If the SSE Event Stream is closed unexpectedly, browsers are supposed to attempt to reconnect automatically. However, in rare situations this does not work and your browser can be left hanging. This extension adds its own reconnection logic (using an exponential-backoff algorithm) on top of the browser’s automatic reconnection, so that your SSE streams will always be as reliable as possible.

Testing SSE Connections with the Demo Server

Htmx includes a demo SSE server written in Node.js that will help you to see SSE in action, and begin bootstrapping your own SSE code. It is located in the /test/ws-sse folder of the htmx-extensions repository. Look at /test/ws-sse/README.md for instructions on running and using the test server.

Migrating from Previous Versions

Previous versions of htmx used a built-in tag hx-sse to implement Server Sent Events. This code has been migrated into an extension instead. Here are the steps you need to take to migrate to this version:

Old AttributeNew AttributeComments
hx-sse=""hx-ext="sse"Use the hx-ext="sse" attribute to install the SSE extension into any HTML element.
hx-sse="connect:<url>"sse-connect="<url>"Add a new attribute sse-connect to the tag that specifies the URL of the Event Stream. This attribute must be in the same tag as the hx-ext attribute.
hx-sse="swap:<EventName>"sse-swap="<EventName>"Add a new attribute sse-swap to any elements that will be swapped in via the SSE extension. This attribute must be placed on or inside of the tag containing the hx-ext attribute.
hx-trigger="sse:<EventName>"NO CHANGEany hx-trigger attributes do not need to change. The extension will identify these attributes and add listeners for any events prefixed with sse:

Listening to events dispatched by this extension

This extension dispatches several events. You can listen for these events like so:

document.body.addEventListener('htmx:sseBeforeMessage', function (e) {
    // do something before the event data is swapped in
})

Each event object has a detail field that contains details of the event.

htmx:sseOpen

This event is dispatched when an SSE connection has been successfully established.

Details
  • detail.elt - The element on which the SSE connection was setup. This is the element which has the sse-connect attribute.
  • detail.source - The EventSource object.

htmx:sseError

This event is dispatched when an SSE connection could not be established.

Details

htmx:sseBeforeMessage

This event is dispatched just before the SSE event data is swapped into the DOM. If you don’t want to swap call preventDefault() on the event. Additionally the detail field is a MessageEvent - this is the event created by EventSource when it receives an SSE message.

Details
  • detail.elt - The swap target.

htmx:sseMessage

This event is dispatched after the SSE event data has been swapped into the DOM. The detail field is a MessageEvent - this is the event created by EventSource when it receives an SSE message.

htmx:sseClose

This event is dispatched in three different closing scenario. To control for the scenario the user can control for the evt.detail.sseclose property.

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
        ...
    }
})
Details
  • detail.elt - The swap target.

Additional SSE Resources

联系我们 contact @ memedata.com