更新记录
1.0.0(2026-07-28)
- 首次发布跨端 SSE UTS API,支持 Android、iOS、HarmonyOS NEXT 与微信小程序。
- 支持标准 SSE 解析、安全重连、POST 幂等恢复及 OpenAI/Anthropic 数据解析。
- 提供稳定错误码与本地脱敏诊断,不上传业务数据。
平台兼容性
uni-app(5.15)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | × | × | √ | 1.0.0 | √ | 1.0.0 | 5.0 | 1.0.0 | 12 | 1.0.0 | √ | 1.0.0 |
| 微信小程序 | 微信小程序插件版本 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.15)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 | 微信小程序 | 微信小程序插件版本 |
|---|---|---|---|---|---|---|---|---|---|
| × | × | 5.0 | 1.0.0 | 12 | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 |
Longde SSE · 原生流式通信
longde-sse 是面向 AI 对话与实时推送的跨端 SSE UTS 插件,适用于 uni-app 与 uni-app x。它提供标准 SSE 协议解析、安全重连、POST 幂等恢复、AI 数据帧辅助解析和可复制的脱敏诊断。
核心能力
- GET、POST 与其他自定义 HTTP 方法
- 自定义请求头和 UTF-8 请求体
- 标准 SSE
data、event、id、retry字段解析 - 多行
data合并、注释/心跳忽略 - UTF-8 字节分片、BOM 与 CR/LF/CRLF 边界处理
- HTTP 状态码与响应头回调
- 主动取消、连接超时、读取超时
- GET/HEAD 可选自动重连、指数退避与 Last-Event-ID 续传
- POST 显式幂等键保护下的可选自动恢复
- 安全的同源/跨源重定向策略与 HTTPS 降级保护
- Cookie 默认隔离,可显式启用会话 Cookie
- 事件类型过滤、重连随机抖动与连接状态查询
- 手动暂停/恢复,以及宿主驱动的断网和前后台恢复
- OpenAI-compatible、Anthropic 与原始 AI 数据帧辅助解析,思考增量与最终回答分离
- 不保存请求内容,不内置任何服务端密钥
安装
将插件目录放入项目:
uni_modules/longde-sse
UTS 插件的运行和原生编译需要 HBuilderX。Android 与 iOS 原生实现不依赖第三方 SDK。
平台与宿主
建议使用 HBuilderX 5.15+。插件支持 Android、iOS、HarmonyOS NEXT、微信小程序,以及 uni-app Vue 2、Vue 3 和 uni-app x。
| 宿主与平台 | 支持情况 | 使用说明 |
|---|---|---|
| uni-app Vue 2/3 + Android/iOS | 支持 | 通过 UTS 原生传输实现。 |
| uni-app x + Android/iOS | 支持 | 支持 VDOM;iOS 还支持 Vapor。 |
| uni-app x + HarmonyOS NEXT | 支持 | 采用 ArkTS 适配;Cookie、重定向和 HTTP 状态能力以运行时能力快照为准。 |
| uni-app x + 微信小程序 | 支持 | 采用分块请求适配;需配置 HTTPS 和微信合法 request 域名。 |
| Web 与其他小程序 | 不支持 | - |
付费 UTS 插件在 HarmonyOS NEXT 或微信小程序上使用时,需要 DCloud 云端编译,因此这两个目标当前要求 uni-app x 宿主。
当前版本已完成 Android 真机自动化、iOS 与 HarmonyOS NEXT 模拟器自动化,以及微信开发者工具的流式页面人工查看。iOS、HarmonyOS NEXT 与微信小程序尚未做真机验收;这不是功能限制,而是当前版本公开的验证边界。
从零开始使用
从插件目录导入 connect,传入 URL 和 onMessage 即可建立连接。connect() 立即返回一个 SSEClient,网络请求和参数校验都在异步流程中执行;因此请在 onError 中处理失败,而不是使用同步 try/catch 等待它抛错。
import { connect } from '@/uni_modules/longde-sse'
const client = connect({
url: 'https://api.example.com/events',
onMessage(event) {
// event.data 是服务端一条完整 SSE data 内容
console.log(event.event, event.id, event.data)
},
onError(error) {
// 使用稳定数字 errCode 做业务分支;不要依赖 errMsg 文本。
console.error(error.errCode, error.errMsg, error.data?.diagnosticId)
},
onClose(event) {
console.log('closed:', event.reason)
}
})
// 页面卸载、用户取消对话时调用;可重复调用。
client.close()
connect(options) 参数参考
url 和 onMessage 是必填项,其余均可省略。所有超时单位都是毫秒。请求头使用对象数组,不是普通对象,以便跨端保持一致的顺序和校验规则。
请求与诊断参数
| 参数 | 类型 | 默认值 / 范围 | 作用与格式 |
|---|---|---|---|
url |
string,必填 |
HTTP(S),最长 8192 字符 | SSE 接口地址,例如 https://api.example.com/events。不支持 ws:、相对路径和空字符串。 |
method |
string |
GET,最长 32 字符 |
HTTP 方法,例如 GET、POST。必须是合法 HTTP token。 |
headers |
Array<{ name: string, value: string }> |
无,最多 64 项 | 请求头,例如 [{ name: 'Authorization', value: 'Bearer xxx' }]。名称大小写不敏感且不能重复,名称和值不能含换行符。 |
body |
string |
无 | UTF-8 请求体,通常为 JSON.stringify(...) 的结果。GET 和 HEAD 会忽略它。插件不会记录该内容。 |
connectTimeout |
number |
15000;1–120000 |
从发起请求到收到 HTTP 响应的最长等待时间。 |
readTimeout |
number |
0;或 1000–86400000 |
已连接后两次收到网络字节之间的最长等待时间;0 表示不设读取超时,适合长期 SSE。 |
diagnosticsMaxEvents |
number |
200;1–200 |
当前 client 在内存中保留的脱敏诊断事件数量;不是日志上传开关。 |
eventTypes |
Array<string> |
不传或 [] 为全部;最多 32 项 |
仅派发指定的 SSE event: 类型,例如 ['message', 'delta']。 |
自动重连与 POST 恢复
默认不重连。GET/HEAD 设置 reconnect: true 后可使用下表策略。POST 可能有副作用或产生 AI 计费,必须同时设置 reconnectPost: true 与稳定的 idempotencyKey,并由服务端按该键去重。
| 参数 | 类型 | 默认值 / 范围 | 作用 |
|---|---|---|---|
reconnect |
boolean |
false |
是否启用自动重连。未开启时连接断开即结束。 |
reconnectMaxRetries |
number |
3;0–10 |
首次连接之后最多额外尝试多少次;0 表示不再尝试。 |
reconnectInitialDelay |
number |
1000;100–60000 |
第一次重连前的等待时间。 |
reconnectMaxDelay |
number |
30000;不小于初始值、最多 300000 |
指数退避等待时间的上限。 |
reconnectBackoffFactor |
number |
2;1–4 |
每次等待的乘数;例如 2 为 1 秒、2 秒、4 秒。 |
reconnectJitterRatio |
number |
0;0–1 |
等待时间的随机浮动比例;0.2 代表最多上下浮动 20%,用于避免集中重连。 |
reconnectUseServerRetry |
boolean |
false |
是否采用服务端 SSE retry: 字段;开启后等待时间至少为 100ms。 |
reconnectOnEof |
boolean |
false |
服务端正常关闭流(EOF)后是否也重连。 |
reconnectWithLastEventId |
boolean |
false |
是否维护服务端 id: 并在重连时发送 Last-Event-ID。 |
reconnectPost |
boolean |
false |
显式允许 POST 自动重试;仅与 reconnect、idempotencyKey 同时使用才有效。 |
idempotencyKey |
string |
1–256 字符 | POST 重试的稳定请求键;同一次业务请求必须固定,例如 chat- 加本次请求 UUID。 |
idempotencyHeader |
string |
Idempotency-Key |
向服务端发送幂等键所使用的 Header 名称。 |
安全、重定向、Cookie 与生命周期参数
| 参数 | 类型 | 默认值 / 范围 | 作用 |
|---|---|---|---|
redirectPolicy |
'never' \| 'same-origin' \| 'always' |
'same-origin' |
重定向策略:拒绝全部、仅同源、或允许跨源。非 GET/HEAD 只接受 307/308,避免请求体或方法被改写。 |
maxRedirects |
number |
5;0–10 |
最多允许的跳转次数。 |
allowInsecureRedirect |
boolean |
false |
是否允许 HTTPS 降级跳转到 HTTP;生产环境不建议开启。 |
allowCrossOriginSensitiveHeaders |
boolean |
false |
跨源跳转时是否仍携带敏感 Header;默认会移除 Authorization、Cookie、Proxy-Authorization。 |
sensitiveHeaders |
Array<string> |
无,最多 32 项 | 除内置敏感 Header 外,还要在跨源跳转时移除的名称,例如 ['X-Api-Key']。 |
cookiePolicy |
'omit' \| 'include' |
'omit' |
默认不读写 Cookie;include 才启用当前 client 的会话 Cookie。请先用 getCapabilities() 确认平台支持程度。 |
pauseOnNetworkLoss |
boolean |
false |
宿主调用 notifyNetworkChange(false) 时是否暂停。 |
resumeOnNetworkAvailable |
boolean |
false |
网络恢复通知到来时,是否恢复因断网暂停的连接。 |
pauseOnBackground |
boolean |
false |
宿主调用 notifyAppBackground() 时是否暂停。 |
resumeOnForeground |
boolean |
false |
回到前台通知到来时,是否恢复因后台暂停的连接。 |
回调参数与数据结构
| 回调 | 触发时机 | 参数结构 |
|---|---|---|
onOpen(event) |
收到合法 2xx SSE 响应后;每次成功重连也会触发 | statusCode、headers: SSEHeader[]、url、redirectCount、operationId、reconnectCount。 |
onMessage(event) |
每条包含 data: 的完整 SSE 事件;必填 |
data(已合并多行 data)、event(未设置时为 message)、id: string \| null、retry: number \| null。 |
onReconnect(event) |
已决定重连、等待开始前 | attempt(从 1 开始)、delay、trigger、lastEventId、operationId。 |
onError(error) |
参数错误、不可恢复的网络/HTTP/协议错误;最多一次 | errCode、errMsg,以及 error.data 的 diagnosticId、operationId、stage、retryable、statusCode、nativeCode。 |
onClose(event) |
连接最终结束;最多一次 | cancelled、reason(cancelled / eof / no-content / failed)、state、operationId。 |
回调顺序为:成功连接时 onOpen → 零到多次 onMessage → onClose;失败时 onError → onClose。HTTP 非 2xx 或错误 Content-Type 不会触发 onOpen。
SSEClient 方法参考
| 方法 | 返回值 | 用法 |
|---|---|---|
close() |
void |
取消当前请求及等待中的重连,最终关闭原因是 cancelled;可重复调用。 |
pause() / resume() |
void |
暂停当前尝试但不产生最终 onClose;resume() 创建新的连接尝试。 |
notifyNetworkChange(isConnected) |
void |
将宿主网络变化传给 client;需配合网络暂停/恢复开关。 |
notifyAppBackground() / notifyAppForeground() |
void |
将宿主前后台变化传给 client;需配合前后台暂停/恢复开关。 |
getState() |
状态字符串 | 返回 connecting、open、reconnecting、paused、closing、closed 或 failed。 |
isClosed() |
boolean |
在 closed 或 failed 返回 true。 |
getOperationId() |
string |
获取本次 client 生命周期固定的追踪 ID。 |
getReconnectCount() / getLastEventId() |
number / string \| null |
获取已重连次数和最近服务端事件 ID。 |
getLastErrorCode() / getLastCloseReason() |
错误码或关闭原因 / null |
获取最终错误码或关闭原因。 |
getNextReconnectDelay() |
number \| null |
重连等待中返回计划延迟,否则返回 null。 |
getCurrentUrl() |
string |
获取当前请求 URL。 |
getDiagnosticReport() / clearDiagnostics() |
string / void |
导出或清空仅存在内存中的脱敏诊断;不会自动上传。 |
平台能力检测
调用 getCapabilities() 后再启用 Cookie、重定向或后台连接等依赖平台的策略。它返回 platform(android / ios / harmony / mp-weixin)、streaming、postStreaming、lastEventId、backgroundStreaming,以及 reconnect、cookiePolicy、redirectPolicy、httpStatus 的支持等级。
import { getCapabilities } from '@/uni_modules/longde-sse'
const capabilities = getCapabilities()
if (capabilities.cookiePolicy !== 'native') {
// 改用无 Cookie 的 Bearer Token,或禁用依赖会话 Cookie 的入口。
}
AI 流式对话示例
import { connect } from '@/uni_modules/longde-sse'
const requestId = 'chat-' + Date.now().toString()
const client = connect({
url: 'https://example.com/v1/chat/completions',
method: 'POST',
headers: [
{ name: 'Authorization', value: 'Bearer ' + token },
{ name: 'Content-Type', value: 'application/json' }
],
body: JSON.stringify({
model: 'your-model',
stream: true,
messages: [{ role: 'user', content: '你好' }]
}),
onOpen(event) {
console.log('SSE connected', event.statusCode)
},
onMessage(event) {
if (event.data == '[DONE]') {
client.close()
return
}
console.log('chunk', event.data)
},
onError(error) {
const data = error.data
console.error(error.errCode, error.errMsg, data?.diagnosticId)
},
onClose(event) {
console.log('SSE closed', event.reason)
},
// POST 重试必须与服务端幂等去重配合;不需要恢复时不要开启。
reconnect: true,
reconnectPost: true,
idempotencyKey: requestId,
reconnectMaxRetries: 2
})
推荐由业务后端持有 AI 服务密钥,App 连接自己的后端 SSE 接口。不要把长期有效的服务端密钥写进客户端代码。
parseOpenAICompatibleData(event.data) 可直接取得 kind/text/reasoning/done/metadata/invalid-json/raw;Anthropic 使用 parseAnthropicData,私有协议使用 parseRawAIData。reasoning 仅用于展示模型思考增量,不能混入最终回答或下一轮上下文。这些函数是无状态解析器,不会改变 SSE 连接、重连和诊断行为。
行为约定
- 默认请求方法为
GET。 - 默认建连超时为 15 秒。
- 默认读取超时为
0,即允许长连接一直等待下一条数据。 - 只有包含至少一个
data字段的事件才触发onMessage。 - 服务端正常结束时
onClose.reason为eof;HTTP 204 为no-content;主动关闭时为cancelled。 - 自动重连默认关闭;GET/HEAD 可通过
reconnect: true启用,其余策略使用reconnectMaxRetries等顶层字段。POST 只有同时启用reconnectPost并提供稳定idempotencyKey才允许重试,且服务端必须按该键去重。 - 自动重连会处理网络错误、超时、HTTP 429/5xx 和可选 EOF,支持服务端
retry:与Last-Event-ID续传。 client.getState()返回connecting/open/reconnecting/paused/closing/closed/failed;close()可重复调用。pause()取消当前请求但不终结 client,resume()重新连接;网络与前后台通知均需宿主接入,自动暂停/恢复开关默认关闭。- 可查询最后错误、关闭原因、当前 URL 和下一次重连等待。
- 启用重连后状态还可能为
reconnecting;close()会同时取消等待中的重连。 client.getDiagnosticReport()可导出仅在内存中保存的脱敏诊断 JSON,插件不会自动上传。- 单行上限为 256 KiB,单事件上限为 1 MiB;越界返回
7002,防止异常服务端无限占用内存。 event.retry是服务端最新的合法重连提示;只有显式启用自动重连时才会用于下一次等待时间。
错误码与排查
错误对象的 errSubject 固定为 longde-sse::connect。error.data 中可取得不含密钥和正文的 diagnosticId,可随问题描述发送至 longdecloud@163.com 协助排查。插件不会自动上传诊断信息。
| errCode | 名称 | 含义与建议 |
|---|---|---|
| 1001 | INVALID_URL | URL 为空、过长或不是 HTTP(S),请修正参数。 |
| 1002 | INVALID_METHOD | HTTP 方法不合法,请修正参数。 |
| 1003 | INVALID_HEADER | 请求头数量、名称、值或重复项不合法。 |
| 1004 | INVALID_TIMEOUT | 建连或读取超时配置无效。 |
| 1005 | INVALID_DIAGNOSTICS | 诊断缓冲区事件数配置无效。 |
| 1006 | INVALID_RECONNECT | 自动重连、退避或 Last-Event-ID 配置无效。 |
| 1007 | INVALID_TRANSPORT_POLICY | 重定向、Cookie、敏感请求头或事件过滤策略无效。 |
| 1008 | CAPABILITY_UNSUPPORTED | 当前平台不支持所请求的能力组合;请先调用 getCapabilities() 调整策略。 |
| 4001 | INVALID_NATIVE_RESPONSE | 原生桥接响应无效;请导出诊断后反馈。 |
| 5001 | HTTP_ERROR | 服务端返回非 2xx;429 和 5xx 可按业务策略重试。 |
| 5002 | NETWORK_ERROR | DNS、TLS、断网或系统 I/O 失败。 |
| 5003 | CONNECT_TIMEOUT | 收到 HTTP 响应前超时。 |
| 5004 | READ_TIMEOUT | 已建立响应后等待后续字节超时。 |
| 5005 | REDIRECT_ERROR | 跳转被策略拒绝、地址无效或次数超限。 |
| 7001 | INVALID_CONTENT_TYPE | 响应不是 text/event-stream。 |
| 7002 | PARSE_ERROR | SSE 单行或单事件超过安全上限等解析失败。 |
| 9001 | INTERNAL_ERROR | 未分类原生错误;请导出诊断后反馈。 |
“可重试”只表示传输层可能恢复。对 AI 的 POST 流,请使用请求幂等键和服务端去重,避免重复生成或重复计费。
隐私说明
插件仅向调用方传入的 URL 发起请求。请求头、请求体与流式响应仅在本次连接的内存中处理,不会被插件另行收集、持久化或上传。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 0
赞赏 0
下载 12467061
赞赏 1936
赞赏
京公网安备:11010802035340号