SSE 分帧核(WHATWG HTML 9.2.6,与客户端无关):字节进、事件出;外加服务端用的拼帧(event-frame /
comment-frame / retry-frame,帧是 UTF-8 字节)。移植自 Keelson jvm/modules/clj-net/src/im/ttalk/net/sse.clj
(5c745869),逻辑未改;不搬阻塞读者与断线续读循环(designs/http-module.md §1.3:无调用方)。拼帧起初也没搬,
clj-agent-server 的 SSE 成了调用方后补上(designs/server-module.md §2)。
:event-type(缺省 "message"):data(多行 data 以 \n 连接):last-event-id(到这个事件为止最近一次
id: 的值,跨事件保留):reconnection-ms(这个事件自己带的 retry:,没有 nil)。(parse-all "event: chat\ndata: a\ndata: b\n\n") ;; => [{:event-type "chat" :data "a\nb" …}]
(let [p (parser)] (feed! p bytes) (take-event! p)) ;; 增量
SSE 分帧核(WHATWG HTML 9.2.6,与客户端无关):字节进、事件出;外加服务端用的拼帧(`event-frame` /
`comment-frame` / `retry-frame`,帧是 UTF-8 字节)。移植自 Keelson `jvm/modules/clj-net/src/im/ttalk/net/sse.clj`
(5c745869),逻辑未改;**不搬**阻塞读者与断线续读循环(designs/http-module.md §1.3:无调用方)。拼帧起初也没搬,
clj-agent-server 的 SSE 成了调用方后补上(designs/server-module.md §2)。
- 事件 = map:`:event-type`(缺省 "message")`:data`(多行 data 以 \n 连接)`:last-event-id`(到这个事件为止最近一次
id: 的值,跨事件保留)`:reconnection-ms`(这个事件自己带的 retry:,没有 nil)。
- 行结束收 \n、\r\n、\r(CRLF 被拆在两次 feed 之间也只算一次);按 UTF-8 解码、去 BOM,charset= 被规范忽略;
流在事件中途结束时那半个事件不派发。
```clojure
(parse-all "event: chat\ndata: a\ndata: b\n\n") ;; => [{:event-type "chat" :data "a\nb" …}]
(let [p (parser)] (feed! p bytes) (take-event! p)) ;; 增量
```(comment-frame text)注释帧(常用作心跳):": text\n\n"。客户端解析器不把它当事件。
注释帧(常用作心跳):": text\n\n"。客户端解析器不把它当事件。
(event-frame data)(event-frame data {:keys [event id retry-ms]})一个事件帧(UTF-8 字节)。opts::event :id :retry-ms(非负)。字段次序钉死为 retry → id → event → data;
多行 data 按 \r\n、\r、\n 拆成多个 data: 字段,输出里不留 \r。id / event 含换行或 NUL ⇒ ex-info
(ex-data :im.ttalk.http/code = "sse/field-no-newline");retry-ms 为负 ⇒ "sse/retry-want-nonneg-int"。
一个事件帧(UTF-8 字节)。`opts`:`:event` `:id` `:retry-ms`(非负)。字段次序钉死为 retry → id → event → data; 多行 data 按 \r\n、\r、\n 拆成多个 data: 字段,输出里不留 \r。id / event 含换行或 NUL ⇒ ex-info (ex-data `:im.ttalk.http/code` = "sse/field-no-newline");retry-ms 为负 ⇒ "sse/retry-want-nonneg-int"。
(parse-all body)整段 SSE(串按 UTF-8,或字节数组)⇒ 事件向量。结尾没有空行收尾的半个事件不算。
整段 SSE(串按 UTF-8,或字节数组)⇒ 事件向量。结尾没有空行收尾的半个事件不算。
(parser)(parser last-event-id)新的分帧核(可变,非线程安全)。last-event-id:续读时从上一条连接的 last event ID 接着算。
新的分帧核(可变,非线程安全)。`last-event-id`:续读时从上一条连接的 last event ID 接着算。
(parser-last-event-id p)最近一次 id: 的值(跨事件保留)。
最近一次 id: 的值(跨事件保留)。
(retry-frame ms)只发 retry:"retry: ms\n\n"。负数 ⇒ IllegalArgumentException。
只发 retry:"retry: ms\n\n"。负数 ⇒ IllegalArgumentException。
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |