更新记录
1.2.1(2026-07-24)
- 修复 Android 编译时
String.charCodeAt()被推断为可空Number?,导致 SSE UTF-8 字节统计与 retry 数字校验无法参与比较的问题。 - 增加解析器可空数值回归守卫,保持 SSE、Line、JSONL、Raw 的解析行为和公开 API 不变。
1.2.0(2026-07-24)
- 新增网络恢复与 App 前后台恢复策略;自动监听网络变化,并支持在
App.vue中通过notifyStreamAppState精确通知生命周期。 - 新增
getMetrics()连接指标快照,覆盖连接、首字节、消息、字节、错误、重连、批处理与环境恢复计数。 - 新增
exportDiagnostics()脱敏诊断报告,仅保留必要配置、指标和最近 50 条生命周期事件,不保存查询参数、请求头值、请求体或消息正文。 - 新增
reconnect()手动立即恢复连接,并统一网络恢复、前台恢复与手动恢复的重连次数控制。 - 新增
batch、onChunkBatch、onMessageBatch高频回调批处理,默认关闭,不改变 1.1.0 的逐条回调行为。 - uni-app 与 uni-app x 示例升级为 1.2.0,补充恢复事件、批量消息、指标快照和诊断报告演示。
1.1.0(2026-07-24)
- 新增 uni-app 与 uni-app x 微信小程序真实分块流式请求,继续复用
connectStream、closeAllStreams和getStreamCapabilities。 - 基于
uni.request({ enableChunked: true })、RequestTask.onHeadersReceived和onChunkReceived接收流式响应,并支持幂等abort()。 - 新增微信小程序增量 UTF-8 解码器,处理中文、Emoji、BOM 和多字节字符跨网络分片。
- 微信端统一支持 SSE、Line、JSONL、Raw,以及 GET/POST/PUT/PATCH/DELETE、自定义请求头、请求体、Last-Event-ID 和可控重连。
- 示例与 README 增加合法请求域名、服务端分块、开发工具/真机差异和小程序后台连接限制说明。
- 测试服务显式启用
Transfer-Encoding: chunked并立即刷新响应头,便于验证首包与真实分块。
平台兼容性
uni-app(5.07)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(5.07)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
lizhao-sse-pro
lizhao-sse-pro 是面向 AI 对话、智能客服、消息推送、日志流和长任务进度的专业 UTS 流式请求插件。一次接入即可在 Android、iOS、HarmonyOS、Web、微信小程序中统一处理 SSE、逐行文本、JSONL 和 Raw 文本流。
插件不是对 EventSource 的简单包装:它支持 POST/PUT/PATCH/DELETE、自定义请求头与请求体、严格 UTF-8 增量解码、首包保护、SSE 标准字段、Last-Event-ID、可控重连、超时、限流和幂等取消。
功能特色
- 四种流协议:
sse / line / jsonl / raw,同一套回调处理不同服务端格式。 - 不局限 GET:支持 GET、POST、PUT、PATCH、DELETE,可接 OpenAI 兼容接口、私有 AI 网关和业务流接口。
- 两种请求头写法:兼容
headers动态对象,同时推荐跨端更稳定的headerList强类型数组。 - 首包不丢:所有回调在网络请求发出前完成注册,适配“连接后立即返回第一段”的服务端。
- 完整 SSE 语义:支持 BOM、CR/LF/CRLF、注释心跳、多行
data、event、id、retry和未知字段忽略。 - UTF-8 分片安全:Android、iOS、HarmonyOS、Web、微信小程序都会保留不完整多字节尾部,中文和 Emoji 不会因网络分片乱码。
- 断线续传:可将最近
id自动写入下一次请求的Last-Event-ID。 - 可控重连:默认关闭,支持最大次数、指数退避、抖动和服务端
retry;避免 POST 默认重放。 - 网络与前后台恢复:自动感知网络变化,可在 App 回到前台后按策略立即恢复,并在离线或后台期间暂停无意义重试。
- 连接指标:通过
getMetrics()随时读取连接耗时、首字节、消息、字节、错误、重连和恢复次数。 - 脱敏诊断:
exportDiagnostics()生成可直接交给技术支持的 JSON 报告,不包含 URL 查询参数、请求头值、请求体或消息正文。 - 高频批处理:可按时间窗口或数量合并 chunk/message 回调,减少 AI 高频 token 对页面渲染的压力。
- 生命周期明确:
idle → connecting → open → reconnect-wait / closed,abort()可重复调用,最终完成回调只触发一次。 - 安全边界:默认不打印 URL 查询参数、请求头、Token、请求体或业务消息;可设置缓冲区和单消息上限。
- 微信真实分块:使用
uni.request({ enableChunked: true })和RequestTask.onChunkReceived,不是等待完整响应后伪装流式。 - 无额外网络 SDK:Android 使用
HttpURLConnection,iOS 使用URLSessionDataDelegate,HarmonyOS 使用requestInStream,Web 使用 Fetch 流,微信使用 RequestTask。 - HarmonyOS 源码实现:不依赖加密
module.har,规避插件导入或云打包时找不到 HAR 的问题。
适用业务场景
- AI 对话、知识库问答、智能客服逐字输出
- 服务端事件推送、告警、排队状态和任务进度
- 流式日志、设备遥测、后台作业状态
- NDJSON / JSONL 数据管道
- 需要 Authorization、自定义签名头或 POST JSON 的流式接口
- 需要手动取消、自动重连、断线续传或并发多连接的业务
接入方式选择
| 你的服务端格式 | 推荐配置 | 典型场景 | 注意事项 |
|---|---|---|---|
text/event-stream |
protocol: 'sse' |
AI 对话、事件推送 | 服务端每个事件以空行结束 |
| 每行一条纯文本 | protocol: 'line' |
日志、逐行进度 | 支持 \n / \r / \r\n |
| 每行一个 JSON | protocol: 'jsonl' |
NDJSON 数据流 | 无效 JSON 会返回 9098011 |
| 任意文本分片 | protocol: 'raw' |
自定义协议或调试 | 分片边界由网络决定,不等于业务消息边界 |
| 只需 GET SSE | GET + sse |
普通事件流 | 可开启安全重连 |
| 需要鉴权或参数 | headerList + POST jsonBody |
私有 AI 接口 | POST 重连默认关闭,避免重复提交 |
| Web 页面 | Web Fetch 流 | H5 管理台 | 服务端必须配置 CORS,代理不能缓存流 |
| 微信小程序 | enableChunked 分块流 |
小程序 AI 对话、进度推送 | 必须配置 HTTPS 合法请求域名,后台连接受微信限制 |
| 弱网与前后台切换 | reconnect + recovery |
移动端 AI 对话、消息流 | App.vue 需转发 onShow/onHide |
| 高频 token 输出 | batch + onMessageBatch |
大模型逐字输出 | 建议先批量合并,再更新页面 |
| 客户现场排障 | getMetrics() + exportDiagnostics() |
首包慢、频繁断流 | 报告已脱敏,可安全收集 |
插件是 API 插件,不包含固定聊天 UI。这样可直接接入你现有的聊天页、Markdown 渲染器、状态管理和业务组件。
安装与运行前准备
- 在 DCloud 插件市场导入插件,确认目录为
uni_modules/lizhao-sse-pro。 - 页面始终从插件根目录导入,不要指向
utssdk/index.uts。 - Android、iOS、HarmonyOS 首次接入或升级原生代码后,需要重新制作并安装自定义基座。
- Web 无需自定义基座,但服务端必须允许当前站点跨域访问并关闭响应缓冲。
- 微信小程序无需自定义基座,但必须在微信公众平台配置 HTTPS 合法请求域名;正式版不能依赖开发工具的“忽略域名校验”。
- 生产接口建议使用 HTTPS,不要把 Token 写死在源码或日志中。
仓库自带本地测试服务:
# 在项目根目录执行;服务默认监听 0.0.0.0:8787,允许局域网真机访问
D:\HBuilderX\plugins\node\node.exe uni_modules\lizhao-sse-pro\example\server\lizhao-sse-pro-test-server.js
也可以使用系统 Node:
node uni_modules/lizhao-sse-pro/example/server/lizhao-sse-pro-test-server.js
| 运行环境 | 示例地址 | 说明 |
|---|---|---|
| Web / 同一台电脑 | http://127.0.0.1:8787 |
浏览器与测试服务运行在同一台电脑 |
| Android 模拟器 | http://10.0.2.2:8787 |
Android Studio 模拟器访问宿主机的默认映射 |
| Android/iOS/HarmonyOS 真机 | http://<电脑局域网IPv4>:8787 |
手机和电脑需在同一网络,防火墙需放行 8787 端口 |
| 微信开发者工具 | 已备案的 HTTPS 测试域名 | 本地 HTTP 只适合临时开发调试,发布前必须切换合法请求域名 |
测试服务默认监听 0.0.0.0,但控制台只展示安全的本机地址和真机地址提示。服务已内置 Web 示例需要的 CORS 预检与响应头,无需另外安装代理。需要限制监听网卡时可设置 LIZHAO_SSE_TEST_HOST=127.0.0.1;端口可通过 LIZHAO_SSE_TEST_PORT 修改。
最小可运行示例
uni-app 示例
import { connectStream } from '@/uni_modules/lizhao-sse-pro'
const connection = connectStream({
url: 'https://example.com/events',
// 回调与参数一次性传入,插件会先注册回调再发起请求。
onMessage(message) {
console.log('收到完整事件:', message.data)
},
onError(error) {
console.log('连接失败:', error.errCode, error.errMsg)
},
onComplete(event) {
console.log('连接最终结束:', event.reason)
}
})
// 页面离开或用户点击停止时调用;重复调用是安全的。
connection.abort()
uni-app x 示例
import {
connectStream,
type StreamConnection,
type StreamMessage,
type StreamFail
} from '@/uni_modules/lizhao-sse-pro'
let connection: StreamConnection | null = null
connection = connectStream({
url: 'https://example.com/events',
protocol: 'sse',
onMessage: (message: StreamMessage): void => {
console.log('收到完整事件:' + message.data)
},
onError: (error: StreamFail): void => {
console.log('连接失败:' + error.errCode.toString())
},
onComplete: (event): void => {
console.log('连接最终结束:' + event.reason)
connection = null
}
})
微信小程序最小示例
微信小程序仍从插件根目录导入,API 与 App/Web 相同;插件内部会启用 enableChunked 并在 RequestTask 创建后立即注册分片监听。
import { connectStream } from '@/uni_modules/lizhao-sse-pro'
const connection = connectStream({
// 必须提前配置为微信小程序合法请求域名。
url: 'https://stream.example.com/events',
protocol: 'sse',
onMessage(message) {
console.log('微信小程序收到事件:', message.data)
},
onError(error) {
console.log('微信小程序连接失败:', error.errCode, error.errMsg)
},
onComplete(event) {
console.log('微信小程序连接结束:', event.reason)
}
})
// 页面卸载或用户停止时主动取消,避免残留网络任务。
connection.abort()
常见增强示例
POST JSON、自定义请求头和鉴权
import { connectStream } from '@/uni_modules/lizhao-sse-pro'
const connection = connectStream({
url: 'https://api.example.com/v1/chat/stream',
method: 'POST',
protocol: 'sse',
// 推荐 headerList:Android、iOS、HarmonyOS、Web 的类型行为一致。
headerList: [
{ name: 'Authorization', value: 'Bearer ' + runtimeToken },
{ name: 'X-Customer-ID', value: customerId }
],
jsonBody: {
model: 'your-model',
messages: [
{ role: 'user', content: '你好' }
],
stream: true
},
reconnect: {
// POST 默认不要自动重连,除非服务端提供幂等键并允许安全重放。
enabled: false
},
onMessage: (message): void => {
if (message.data == '[DONE]') {
connection.abort('服务端完成标记')
return
}
console.log(message.data)
},
onError: (error): void => {
console.log('请求失败:' + error.errMsg)
}
})
自动重连与 Last-Event-ID
const connection = connectStream({
url: 'https://example.com/events',
protocol: 'sse',
reconnect: {
enabled: true,
maxAttempts: 5,
initialDelayMs: 1000,
maxDelayMs: 15000,
multiplier: 2,
jitterRatio: 0.2,
useServerRetry: true
},
onRetry: (event): void => {
console.log('第 ' + event.attempt.toString() + ' 次重连将在 ' + event.delayMs.toString() + 'ms 后执行')
},
onMessage: (message): void => {
// 插件会保存 SSE id,并在重连时自动发送 Last-Event-ID。
console.log(message.id + ': ' + message.data)
}
})
网络恢复与 App 前后台恢复
先开启 reconnect,再启用恢复策略。插件会自动监听网络变化;App 生命周期需要从 App.vue 显式通知,避免把页面显示误判成整个应用前后台状态。
// App.vue
import { notifyStreamAppState } from '@/uni_modules/lizhao-sse-pro'
export default {
onShow() {
// App 回到前台,满足最短后台时长后可立即恢复连接。
notifyStreamAppState('foreground')
},
onHide() {
// App 进入后台,后续失败会等待前台恢复,不空转重试。
notifyStreamAppState('background')
}
}
const connection = connectStream({
url: 'https://example.com/events',
reconnect: {
enabled: true,
maxAttempts: 5
},
recovery: {
reconnectOnNetworkRestored: true,
reconnectOnForeground: true,
foregroundMinBackgroundMs: 1000,
deferRetryWhileOffline: true,
deferRetryWhileBackground: true
},
onEnvironmentChange: (event): void => {
console.log('环境变化:' + event.kind + ' / ' + event.networkType + ' / ' + event.appState)
}
})
高频消息批处理
batch 默认关闭。开启后,只有提供了对应批量回调的类型才会停止逐条回调;例如只提供 onMessageBatch 时,onChunk 仍会逐条触发。
const connection = connectStream({
url: 'https://example.com/ai-stream',
batch: {
enabled: true,
intervalMs: 16,
maxItems: 20
},
onMessageBatch: (messages): void => {
// 一批只更新一次响应式状态,降低高频 token 导致的渲染开销。
const text = messages.map((item) => item.data).join('')
appendAssistantText(text)
}
})
指标快照与脱敏诊断
const metrics = connection.getMetrics()
console.log('连接耗时:' + metrics.connectDurationMs.toString() + 'ms')
console.log('首字节:' + metrics.firstByteDurationMs.toString() + 'ms')
// 报告不包含 Authorization/Cookie 值、URL 查询参数、body、chunk 或 message.data。
const diagnosticJson = connection.exportDiagnostics()
console.log(diagnosticJson)
// 需要立即重建当前流时使用;未开启 reconnect 或额度耗尽会返回 false。
const accepted = connection.reconnect('用户点击重新连接')
Line 与 JSONL
// 每个完整文本行触发一次 onMessage。
const lineConnection = connectStream({
url: 'https://example.com/logs',
protocol: 'line',
onMessage: (message): void => console.log(message.data)
})
// 每个非空行必须是合法 JSON;原文在 data,解析结果在 json。
const jsonlConnection = connectStream({
url: 'https://example.com/items.ndjson',
protocol: 'jsonl',
onMessage: (message): void => {
console.log(message.data, message.json)
}
})
状态、超时与大小保护
const connection = connectStream({
url: 'https://example.com/events',
connectTimeoutMs: 15000,
idleTimeoutMs: 45000,
totalTimeoutMs: 0,
maxBufferBytes: 1024 * 1024,
maxMessageBytes: 512 * 1024,
onStateChange: (event): void => {
console.log(event.previousState + ' -> ' + event.state)
},
onChunk: (event): void => {
// onChunk 适合进度统计;业务通常优先使用 onMessage。
console.log('累计字节:' + event.receivedBytes.toString())
}
})
并发连接与统一关闭
import { connectStream, closeAllStreams } from '@/uni_modules/lizhao-sse-pro'
const chatA = connectStream({ url: 'https://example.com/chat/a' })
const chatB = connectStream({ url: 'https://example.com/chat/b' })
// 可单独取消。
chatA.abort()
// 退出账号或销毁业务模块时统一关闭本插件创建的连接。
closeAllStreams()
完整示例源码
- uni-app:
uni_modules/lizhao-sse-pro/example/uniapp/index.vue - uni-app x:
uni_modules/lizhao-sse-pro/example/uniappx/index.uvue - 随插件发布的本地测试服务:
uni_modules/lizhao-sse-pro/example/server/lizhao-sse-pro-test-server.js - 协议分片样本:
scripts/fixtures/lizhao-sse-pro-events.json
完整示例不是简单按钮集合,而是面向首次接入客户的“专业流式控制台”:
- 启动测试服务并按运行环境选择地址。
- 从快速体验或异常诊断中选择场景,页面自动填充安全参数。
- 点击开始连接,观察首包耗时、消息数、接收字节、重连次数、Event ID 和事件时间线。
- 需要调试时再展开高级配置,修改 method、protocol、headers、body、超时、重连和大小限制。
快速体验场景
| 场景 | 端点 | 方法 | 协议 | 验证内容 |
|---|---|---|---|---|
| 基础 SSE | /sse/basic |
GET | SSE | event、id、多行 data、中文 |
| AI POST | /sse/post-echo |
POST | SSE | JSON Body、自定义请求头和方法回显 |
| 中文分片 | /sse/utf8-split |
GET | SSE | 中文与 Emoji 跨网络分片不乱码 |
| 断线续传 | /sse/resume |
GET | SSE | Last-Event-ID 与恢复结果 |
| Line | /line |
GET | Line | LF、CRLF 和跨 chunk 文本行 |
| JSONL | /jsonl |
GET | JSONL | 逐行 JSON 解析结果 |
| Raw | /raw |
GET | Raw | 原始文本分片 |
异常诊断场景
| 场景 | 端点 | 预期结果 |
|---|---|---|
| 立即首包 | /sse/immediate |
验证回调在网络任务前注册,第一条消息不丢 |
| HTTP 401 | /status/401 |
展示状态码和统一错误 |
| 连接超时 | /slow-open |
触发 connectTimeoutMs |
| 空闲超时 | /idle |
触发 idleTimeoutMs |
| 消息超限 | /oversize |
触发 maxMessageBytes 保护 |
| 异常断流 | /drop |
观察错误、重连和完成原因 |
| 多连接隔离 | /multi/{id} |
A/B 两条连接分别返回自己的消息 |
事件时间线区分 open / chunk / message / retry / state / error / complete,默认最多保存 100 条,支持“全部、消息、错误”过滤和自动跟随。页面切换场景、主动取消和卸载都会执行幂等清理,并通过 closeAllStreams() 兜底关闭连接。
README 只保留可复制的关键片段,页面完整模板、状态管理和样式请直接查看上述示例文件。
API 列表
| API | 返回值 | 说明 |
|---|---|---|
connectStream(options) |
StreamConnection |
创建流式连接;立即返回控制对象 |
closeAllStreams() |
void |
幂等关闭本插件创建的全部连接 |
getStreamCapabilities() |
StreamCapabilities |
获取当前平台真实能力矩阵 |
notifyStreamAppState(state) |
void |
从 App.vue 通知前后台状态 |
notifyStreamNetworkChange(isConnected, networkType?) |
void |
手动通知网络状态;通常无需调用 |
connectStream(options)
说明
创建一个流式 HTTP 请求。函数同步返回连接控制对象,网络事件通过 options 中的回调持续返回。所有回调会在请求发出前保存,避免立即首包丢失。
支持平台
Android / iOS / HarmonyOS / Web / 微信小程序;兼容 uni-app 与 uni-app x。
参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
options |
ConnectStreamOptions |
是 | 请求、协议、限制和全生命周期回调 | 无 | 见下表 |
options.url |
string |
是 | HTTP/HTTPS 流地址 | 无 | http:// / https:// |
options.method |
StreamMethod |
否 | HTTP 方法 | GET |
GET / POST / PUT / PATCH / DELETE |
options.protocol |
StreamProtocol |
否 | 消息解析协议 | sse |
sse / line / jsonl / raw |
options.headers |
UTSJSONObject |
否 | 兼容 JS 普通对象的请求头 | 无 | 任意字符串键值 |
options.headerList |
Array<StreamHeader> |
否 | 推荐的强类型请求头;同名时覆盖 headers | [] |
{ name, value } |
options.bodyText |
string |
否 | 文本请求体,与 jsonBody 互斥 | 无 | 无 |
options.jsonBody |
any |
否 | JSON 请求体,与 bodyText 互斥 | 无 | 可 JSON 序列化值 |
options.connectTimeoutMs |
number |
否 | 连接建立超时,毫秒 | 30000 |
大于 0 |
options.idleTimeoutMs |
number |
否 | 打开后无字节到达超时,0 不限制 | 0 |
大于等于 0 |
options.totalTimeoutMs |
number |
否 | 单次连接总时长,0 不限制 | 0 |
大于等于 0 |
options.reconnect |
StreamReconnectOptions |
否 | 自动重连配置 | { enabled: false } |
见下表 |
options.recovery |
StreamRecoveryOptions |
否 | 网络和 App 前后台恢复策略 | 见下表 | 见下表 |
options.batch |
StreamBatchOptions |
否 | 高频回调批处理 | { enabled: false, intervalMs: 16, maxItems: 20 } |
见下表 |
options.lastEventId |
string |
否 | 首次请求的 Last-Event-ID | '' |
无 |
options.maxBufferBytes |
number |
否 | 未完成帧最大缓冲字节数 | 1048576 |
最小 1024 |
options.maxMessageBytes |
number |
否 | 单条完整消息最大字节数 | 524288 |
最小 1024 |
options.debug |
boolean |
否 | 输出精简中文诊断日志 | false |
true / false |
options.logPayload |
boolean |
否 | debug 时打印业务文本,不建议生产开启 | false |
true / false |
options.onOpen |
function |
否 | HTTP 连接打开时触发 | 无 | StreamOpenEvent |
options.onChunk |
function |
否 | 每个 UTF-8 文本分片触发 | 无 | StreamChunkEvent |
options.onChunkBatch |
function |
否 | 批量文本分片;提供后接管 onChunk | 无 | Array<StreamChunkEvent> |
options.onMessage |
function |
否 | 每条完整协议消息触发 | 无 | StreamMessage |
options.onMessageBatch |
function |
否 | 批量完整消息;提供后接管 onMessage | 无 | Array<StreamMessage> |
options.onRetry |
function |
否 | 服务端 retry 更新或等待重连时触发 | 无 | StreamRetryEvent |
options.onStateChange |
function |
否 | 连接状态变化时触发 | 无 | StreamStateEvent |
options.onEnvironmentChange |
function |
否 | 网络或 App 前后台变化时触发 | 无 | StreamEnvironmentEvent |
options.onError |
function |
否 | 单次失败或最终失败时触发 | 无 | StreamFail |
options.onComplete |
function |
否 | 连接最终结束时只触发一次 | 无 | StreamCompleteEvent |
options.success |
function |
否 | 兼容 uni 风格,首次打开时触发 | 无 | StreamOpenEvent |
options.fail |
function |
否 | 兼容 uni 风格,与 onError 同时触发 | 无 | StreamFail |
options.complete |
function |
否 | 兼容 uni 风格,与 onComplete 同时触发 | 无 | StreamCompleteEvent |
重连参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
reconnect.enabled |
boolean |
否 | 是否自动重连 | false |
true / false |
reconnect.maxAttempts |
number |
否 | 最大重连次数 | 3 |
大于等于 0 |
reconnect.initialDelayMs |
number |
否 | 初始等待毫秒数 | 1000 |
大于等于 0 |
reconnect.maxDelayMs |
number |
否 | 最大等待毫秒数 | 30000 |
大于等于 initialDelayMs |
reconnect.multiplier |
number |
否 | 指数退避倍数 | 2 |
大于等于 1 |
reconnect.jitterRatio |
number |
否 | 随机抖动比例 | 0.2 |
0 到 1 |
reconnect.useServerRetry |
boolean |
否 | 是否采用 SSE retry 字段 | true |
true / false |
恢复参数
recovery中任何自动恢复行为都依赖reconnect.enabled: true,并共用maxAttempts次数上限。
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
recovery.reconnectOnNetworkRestored |
boolean |
否 | 断网恢复后立即重连 | false |
true / false |
recovery.reconnectOnForeground |
boolean |
否 | App 回到前台后立即重连 | false |
true / false |
recovery.foregroundMinBackgroundMs |
number |
否 | 触发前台恢复所需最短后台时长 | 1000 |
大于等于 0 |
recovery.deferRetryWhileOffline |
boolean |
否 | 离线时暂停普通重试 | true |
true / false |
recovery.deferRetryWhileBackground |
boolean |
否 | App 后台时暂停普通重试 | true |
true / false |
批处理参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
batch.enabled |
boolean |
否 | 是否启用批处理 | false |
true / false |
batch.intervalMs |
number |
否 | 最长聚合时间 | 16 |
大于 0 |
batch.maxItems |
number |
否 | chunk 与 message 合计达到该数量时立即刷新 | 20 |
大于 0 |
返回值 StreamConnection
| 字段 | 类型 | 说明 |
|---|---|---|
getId() |
() => string |
返回本次连接 ID |
getState() |
() => StreamConnectionState |
返回当前状态 |
getMetrics() |
() => StreamMetrics |
返回当前连接指标快照 |
exportDiagnostics() |
() => string |
导出脱敏 JSON 诊断报告 |
reconnect(reason?) |
(reason?: string) => boolean |
请求立即恢复;返回是否接受 |
abort(reason?) |
(reason?: string) => void |
幂等取消;不会把主动取消当成错误 |
回调数据
StreamMessage
| 字段 | 类型 | 说明 |
|---|---|---|
connectionId |
string |
连接 ID |
protocol |
StreamProtocol |
当前解析协议 |
data |
string |
完整文本消息 |
event |
string |
SSE event;缺省为 message,非 SSE 为空 |
id |
string |
最近一次有效 SSE id |
json |
any \| null |
JSONL 解析结果;其他协议为 null |
sequence |
number |
当前连接消息序号,从 1 开始 |
StreamOpenEvent
| 字段 | 类型 | 说明 |
|---|---|---|
connectionId |
string |
连接 ID |
statusCode |
number |
HTTP 状态码;Harmony 或微信小程序首分片早于响应头时,首次打开事件可能为 0,最终完成事件会补全真实状态码 |
headers |
Array<StreamHeader> |
响应头 |
platform |
string |
当前平台 |
reconnected |
boolean |
是否为重连后的打开 |
StreamCompleteEvent
| 字段 | 类型 | 说明 |
|---|---|---|
connectionId |
string |
连接 ID |
reason |
StreamCompleteReason |
remote-end / abort / error / timeout / reconnect-exhausted |
manuallyAborted |
boolean |
是否主动取消 |
statusCode |
number |
最终状态码 |
reconnectCount |
number |
实际重连次数 |
lastEventId |
string |
最后 SSE 事件 ID |
StreamMetrics
| 字段 | 类型 | 说明 |
|---|---|---|
state |
StreamConnectionState |
生成快照时的状态 |
connectDurationMs |
number |
创建到首次打开耗时;尚未打开为 0 |
firstByteDurationMs |
number |
创建到首字节耗时;尚未收到为 0 |
durationMs |
number |
当前或最终连接生命周期时长 |
receivedBytes |
number |
当前连接累计接收字节数 |
chunkCount |
number |
文本分片数量 |
messageCount |
number |
完整协议消息数量 |
errorCount |
number |
错误回调数量 |
reconnectCount |
number |
已消耗重连次数 |
batchFlushCount |
number |
批处理刷新次数 |
networkChangeCount |
number |
网络状态变化次数 |
foregroundRecoveryCount |
number |
前台恢复次数 |
notifyStreamAppState(state)
说明
在 App 根生命周期中通知插件进入前台或后台。页面级显示隐藏不能完全代表 App 状态,推荐统一放在 App.vue。
参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
state |
StreamAppState |
是 | App 当前状态 | 无 | foreground / background |
返回值
| 字段 | 类型 | 说明 |
|---|---|---|
| 无 | void |
无返回值 |
notifyStreamNetworkChange(isConnected, networkType?)
说明
手动广播网络状态。插件内部已通过 uni.onNetworkStatusChange 自动监听,只有自定义网络探针或特殊运行环境无法监听时才需要调用。
参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
isConnected |
boolean |
是 | 是否有网络连接 | 无 | true / false |
networkType |
string |
否 | 网络类型或自定义标签 | unknown |
wifi / 2g / 3g / 4g / 5g / unknown |
返回值
| 字段 | 类型 | 说明 |
|---|---|---|
| 无 | void |
无返回值 |
closeAllStreams()
说明
关闭本插件当前创建的全部连接。重复调用安全,适合退出账号、切换环境或销毁全局流服务时使用。
参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
| 无 | void |
否 | 无参数 | 无 | 无 |
返回值
| 字段 | 类型 | 说明 |
|---|---|---|
| 无 | void |
无返回值 |
getStreamCapabilities()
说明
同步返回当前平台能力矩阵。建议在页面展示功能入口前调用,不要仅依赖平台字符串猜测能力。
参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
| 无 | void |
否 | 无参数 | 无 | 无 |
返回值
| 字段 | 类型 | 说明 |
|---|---|---|
supported |
boolean |
是否支持真实流 |
platform |
string |
当前平台 |
protocols |
Array<StreamProtocol> |
支持协议 |
methods |
Array<StreamMethod> |
支持方法 |
customHeaders |
boolean |
是否支持自定义请求头 |
requestBody |
boolean |
是否支持请求体 |
reconnect |
boolean |
是否支持自动重连和断线续传 |
responseStatus |
boolean |
是否能提供 HTTP 状态 |
requiresCustomBase |
boolean |
是否需要自定义基座 |
notes |
string |
平台边界说明 |
错误码
| 错误码 | 含义 | 说明 |
|---|---|---|
9098001 |
参数不合法 | URL、请求体互斥或方法参数不符合要求 |
9098002 |
平台不支持 | 当前平台没有真实流式实现 |
9098003 |
网络连接失败 | DNS、TLS、断网、连接中断等 |
9098004 |
连接建立超时 | 超过 connectTimeoutMs |
9098005 |
连接空闲超时 | 打开后超过 idleTimeoutMs 无字节到达 |
9098006 |
连接总时长超时 | 超过 totalTimeoutMs |
9098007 |
HTTP 状态异常 | 状态码不在 200 到 299 |
9098008 |
响应流读取失败 | 系统流读取异常 |
9098009 |
UTF-8 解码失败 | 服务端不是合法 UTF-8 或尾字符不完整 |
9098010 |
协议解析失败 | SSE/Line/Raw 结构处理异常 |
9098011 |
JSONL 无效 | JSONL 某行不是合法 JSON |
9098012 |
缓冲区超限 | 未完成帧超过 maxBufferBytes |
9098013 |
消息超限 | 单条消息超过 maxMessageBytes |
9098014 |
重连耗尽 | 达到 maxAttempts 后仍未恢复 |
支持平台
| 平台 | 是否支持 | 说明 |
|---|---|---|
| uni-app Android | 支持 | Vue2、Vue3、app-vue、app-nvue;需要自定义基座 |
| uni-app iOS | 支持 | URLSession 原生流;需要自定义基座 |
| uni-app HarmonyOS | 支持 | requestInStream 源码实现;需要自定义基座 |
| uni-app Web | 支持 | Fetch 流;受浏览器 CORS 和代理缓冲影响 |
| uni-app x Android | 支持 | 需要自定义基座 |
| uni-app x iOS | 支持 | 需要自定义基座 |
| uni-app x HarmonyOS | 支持 | 不依赖加密 module.har |
| uni-app x Web | 支持 | Fetch / ReadableStream / TextDecoder |
| uni-app 微信小程序 | 支持 | enableChunked + onChunkReceived,需合法请求域名 |
| uni-app x 微信小程序 | 支持 | HBuilderX 5.07+;API 与 App/Web 一致 |
| 其他小程序 | 不支持 | 各平台分块 API 和发布限制不同,不伪造支持 |
权限
| 平台 | 权限或配置 | 说明 |
|---|---|---|
| Android | android.permission.INTERNET |
插件 Manifest 已声明 |
| iOS | 网络访问 | HTTPS 默认可用;HTTP 明文地址需由宿主按业务评估 ATS 配置 |
| HarmonyOS | ohos.permission.INTERNET |
宿主打包时需具备网络权限 |
| Web | CORS | 服务端需允许 Origin、Method 和自定义 Header |
| 微信小程序 | 合法请求域名 | 在微信公众平台配置 HTTPS 域名,不能依赖开发工具关闭校验 |
自定义基座
- Android、iOS、HarmonyOS 的实现包含原生 UTS/原生辅助代码,首次安装和每次原生代码升级后必须重新制作自定义基座。
- 只修改页面、示例 URL 或普通业务代码时,不需要重新制作自定义基座。
- 仅更新 wgt 或 appResource 不能替换已经编译进旧基座的原生代码。
- Web 与微信小程序不需要自定义基座。
服务端建议
- SSE 响应建议设置
Content-Type: text/event-stream; charset=utf-8。 - 微信小程序服务端必须持续刷新响应分块,建议显式使用
Transfer-Encoding: chunked,不能等完整正文生成后一次性返回。 - 每个 SSE 事件以空行结束;多个
data:会按换行合并。 - 代理层关闭缓冲,例如 Nginx 可返回
X-Accel-Buffering: no并按部署策略关闭 proxy buffering。 - 定期发送
: heartbeat注释行,避免网关把空闲连接关闭。 - 需要续传时发送稳定递增的
id:,并识别客户端Last-Event-ID。 - POST 自动重连前必须设计幂等键,防止生成任务、扣费或业务写入重复执行。
- 返回内容必须是合法 UTF-8;插件不会用替换字符静默掩盖非法编码。
常见问题
为什么推荐 headerList,仍然保留 headers?
部分 UTS 平台或 uni-app 动态桥接对普通对象的推断存在差异。插件保留 headers 方便旧代码迁移,同时将它归一化为字符串请求头;新项目优先使用 headerList,类型最明确。同名时 headerList 覆盖 headers。
为什么第一条消息偶尔收不到?
常见原因是先连接、成功后才注册监听。lizhao-sse-pro 将 onOpen/onChunk/onMessage/... 全部放入 connectStream(options),平台层在发起请求前注册原生监听。请不要在 onOpen 之后才动态替换 onMessage。
支持 POST 参数吗?
支持。使用 method: 'POST',并在 bodyText 与 jsonBody 中二选一。jsonBody 会自动序列化,并在客户未配置时补 Content-Type: application/json; charset=utf-8。
retry 和关闭回调是否真的实现?
已实现。合法的 SSE retry: 会更新重连等待;onRetry 会区分 server 与 client。onComplete 和兼容的 complete 只在连接最终结束时触发一次,单次失败后仍要重连时不会提前完成。
HarmonyOS 为什么不会出现缺少 module.har?
HarmonyOS 能力直接使用公开 requestInStream 源码实现,插件没有加密 HAR 依赖,也不会生成指向不存在 module.har 的依赖项。
Web 一直没有消息,但 App 正常
依次检查:
- 浏览器 Network 中是否被 CORS 拦截;
- 预检 OPTIONS 是否允许实际 Method 和 Authorization 等请求头;
- CDN/Nginx 是否缓冲了响应;
- 响应是否真正以分块方式持续发送;
- 页面 HTTPS 时是否请求了被浏览器拦截的 HTTP 混合内容。
微信小程序为什么没有流式回调?
按顺序检查:
- 请求域名是否已配置为微信小程序合法 HTTPS 域名;
- 服务端是否真的持续写入并刷新
Transfer-Encoding: chunked响应; - CDN、网关或 Nginx 是否缓冲了完整响应;
- 是否在页面卸载、切后台或网络切换后被微信运行环境暂停或回收;
- 开发工具可用但真机不可用时,是否仍依赖“忽略域名校验”或本机
127.0.0.1。
微信小程序不承诺后台常驻连接。页面离开时应调用 abort(),回到前台后由业务按需要重新建立连接。
为什么默认不自动重连?
流式接口经常使用 POST 创建生成任务或产生计费。网络失败后自动重放可能造成重复提交,因此安全默认值是关闭。GET 推送流可按业务开启;POST 必须先保证服务端幂等。
onChunk 和 onMessage 该用哪个?
onChunk:网络文本分片,适合统计进度和底层诊断,边界不稳定。onMessage:经过 SSE/Line/JSONL/Raw 解析后的业务消息,绝大多数页面应使用它。
批处理会不会导致原有回调失效?
默认不会,batch.enabled 默认为 false。启用后也只接管已经提供批量回调的类型:提供 onMessageBatch 后不再逐条触发 onMessage,但没有提供 onChunkBatch 时 onChunk 仍照常逐条触发。连接结束、错误或重连前会先刷新剩余批次。
诊断报告能直接发给技术支持吗?
可以。报告只包含插件版本、平台、脱敏 URL、请求头名称、非敏感配置、指标和最近 50 条生命周期事件。不会写入查询参数、请求头值、请求体、chunk 文本或 message.data。发送前仍建议按你公司的数据制度再次检查。
真机为什么访问不了本地测试服务?
手机里的 127.0.0.1 指向手机自身。改用电脑局域网 IP,确保同一网络,并允许防火墙访问测试端口。Android 使用 HTTP 明文地址时还要遵守宿主网络安全策略;生产环境建议 HTTPS。
发布前验收建议
发布包内提供自动守卫和测试服务,覆盖:
- BOM、CR/LF/CRLF、多行 data、event/id/retry
- 立即首包、中文/Emoji 跨字节分片
- POST JSON、Authorization 和自定义请求头
- Last-Event-ID、非 2xx、连接中断
- Line、JSONL、Raw、并发连接
- 连接/空闲/总时长超时
- 缓冲区与单消息上限
- 主动取消、重复取消和最终回调一次性
- 微信小程序合法域名、立即首包、UTF-8 跨分片、POST/headers、取消与前后台恢复
- 断网后等待、网络恢复立即重连、后台暂停重试和回前台恢复
getMetrics()计数与耗时、exportDiagnostics()查询参数和凭据脱敏onMessageBatch时间/数量刷新、错误/重连/完成前刷新剩余消息
自动检查不能替代客户真实网关、代理、证书和实体设备验收。上线前请至少用一个真实接口在目标 Android/iOS/HarmonyOS 设备和微信小程序真机上验证首包、中文、取消和弱网恢复。
隐私与安全
- 插件不采集、不上传、不保存客户账号、Token、请求体或流消息。
debug默认关闭;即使开启,也默认只输出状态和字节数。logPayload会输出业务文本,仅限本地排障,生产环境不要开启。- 错误 details 不包含完整 headers、body 或 URL 查询参数。
- Token 应由安全登录态或短期凭证提供,不要硬编码到插件、页面或示例。
作者系列UTS插件
以下为已在 DCloud 插件市场上架的作者系列 UTS 插件,可按业务场景组合使用。未列出的插件表示当前未确认公开市场页,后续上架后再补充。
| 插件 | 能力方向 | 插件市场 |
|---|---|---|
lizhao-nfc-pro |
NFC 标签读写、NDEF、IsoDep 与诊断 | 查看插件 |
lizhao-float-window |
悬浮窗、画中画、权限与诊断 | 查看插件 |
lizhao-device-id |
设备标识、隐私策略与诊断 | 查看插件 |
lizhao-scan-pro |
原生扫码、连续扫码、相册识别 | 查看插件 |
lizhao-choose-file |
原生文件选择、上传、进度与取消 | 查看插件 |
lizhao-bg-audio |
背景音频播放、队列、倍速与事件 | 查看插件 |
lizhao-smart-tts |
系统 TTS、云端合成、听书方案 | 查看插件 |
lizhao-share-plus |
系统分享、远程文件下载后分享 | 查看插件 |
lizhao-sqlite-pro |
原生 SQLite、迁移、备份与诊断 | 查看插件 |
lizhao-icon-pro |
SVG 图标组件、多主题与缓存 | 查看插件 |
lizhao-cast-screen |
DLNA 投屏、AirPlay 路由入口 | 查看插件 |
lizhao-call-kit |
电话、短信、通讯录原生能力 | 查看插件 |
lizhao-app-keepalive |
应用保活、唤醒、自愈与报告 | 查看插件 |
lizhao-doc-corrector |
文档扫描、矫正、增强与识别 | 查看插件 |
lizhao-emu-detect |
模拟器环境检测、风险评分与证据 | 查看插件 |
lizhao-gallery-pro |
相册媒体分页、筛选、缩略图与导出 | 查看插件 |
lizhao-video-thumb |
视频封面、批量取帧与 Base64 返回 | 查看插件 |
lizhao-ble |
BLE 扫描、连接、读写、通知与自动重连 | 查看插件 |
lizhao-sse-pro |
SSE、Line、JSONL 与 Raw 流式请求 | 查看插件 |

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 6485
赞赏 5
下载 12453640
赞赏 1935
赞赏
京公网安备:11010802035340号