更新记录
1.0.0(2026-06-18) 下载此版本
- 作为
1.0.0起始版本,初始化jz-webrtc-connect通用 WebRTCDataChannel通讯插件,面向uni-app的H5 / App场景。 - 提供统一 SDK 入口,支持通过
configure()保存低频基础配置,并通过connect()发起真实建连。 - 内置
host / client双角色模型,支持房间式实时通讯、单播、Host 广播、心跳保活、ACK、请求响应与客户端自动重连。 - 支持
PeerJS信令模式,适合快速接入已有 PeerServer 的项目。 - 支持
native信令模式,可通过WebSocket或自定义transport交换offer / answer / candidate,服务端仅需负责按roomId与to转发信令消息。 - 支持
custom adapter扩展入口,便于业务方复用插件上层通讯核心,同时接入自定义信令体系。 - 提供可选数据同步模块
DataCore,支持kv / list / map三类命名空间容器,以及 Host 权威数据源下的 patch / snapshot 同步机制。 - 提供基础持久化驱动抽象,内置内存驱动与
uni storage驱动,方便业务按需扩展。 - 提供
renderjs桥接组件骨架,便于后续 App 侧扩展。 - 补充详细文档,重点说明插件用法、配置项、信令模式差异,以及 WebRTC 相比纯 WebSocket 在“打洞成功后业务数据不走服务器、节约带宽与中转资源”方面的优势与边界。
平台兼容性
uni-app(4.74)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | √ | √ | √ | √ | - | √ | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
jz-webrtc-connect
jz-webrtc-connect 从 1.0.0 版本开始,是一个面向 uni-app 的通用 WebRTC DataChannel 通讯插件,支持 H5 / App,用于构建房间协作、实时指令同步、局域网或互联网点对点消息传输等场景。
它聚焦的是“数据通讯”而不是音视频 UI:
- 提供统一的连接核心
ConnectCore - 支持
PeerJS、native WebSocket 信令、custom adapter - 提供可选的数据同步层
DataCore - 支持
host / client双角色模型 - 支持心跳、ACK、请求响应、客户端重连、Host 广播
为什么它比纯 WebSocket 更省资源
很多实时业务一开始会直接上 WebSocket,但纯 WebSocket 有一个天然问题:
- 所有业务数据都必须经过服务器转发
- 房间人数一多,服务端带宽、连接数、转发 CPU、内存压力都会持续上升
- 每条消息都要走“客户端 -> 服务器 -> 客户端”,延迟路径更长
jz-webrtc-connect 的核心优势在于:
- WebSocket 或 PeerServer 主要只负责“信令交换”
- 真正的业务消息走 WebRTC
DataChannel - 在 NAT 打洞成功时,数据直接在终端之间传输,不经过业务服务器
- 服务器不再承担高频业务包转发,资源占用明显更低
可以简单理解为:
- 纯 WebSocket:服务器既负责建链,也负责所有数据中转
- WebRTC DataChannel:服务器主要负责“介绍双方认识”,连通后数据尽量点对点直达
这意味着在打洞成功后,你可以获得这些收益:
- 节约服务器带宽
- 降低消息中转成本
- 降低服务端并发转发压力
- 降低中心节点故障对业务消息面的影响
- 在很多场景下得到更低的传输延迟
重要边界
请务必正确理解 WebRTC 的工作边界:
signal依然是必须的,建连前必须交换offer / answer / candidatenative模式里通常使用 WebSocket 做信令peerjs模式里由 PeerServer 帮你完成信令交换- 如果网络环境复杂,可能需要 TURN 中继
- 一旦退化到 TURN,中继流量会经过 TURN 服务器,不再是完全点对点
所以更准确的表述是:
在 STUN / NAT 打洞成功时,业务数据可绕过业务服务器直连传输;如果必须依赖 TURN,则数据会经过 TURN 中继。
典型场景
- 实时房间控制指令同步
- 多端协作状态同步
- 局域网点对点通讯
- 轻量级实时消息广播
- 低频信令 + 高频业务数据的拆分架构
插件结构分析
src/uni_modules/jz-webrtc-connect 目录大致分为四层:
1. 入口层
js_sdk/jz-webrtc-connect/index.js
对外暴露统一 API:
configure()保存低频基础配置connect()发起一次真实建连getInstance()获取当前连接核心destroy()销毁当前连接createDataCore()创建可选数据同步层
2. 连接层
connect/ConnectCore.jsconnect/HostPeerLink.jsconnect/ClientPeerLink.jsconnect/PeerLinkBase.jsconnect/HeartbeatMonitor.jsconnect/MessageCodec.js
职责是:
- 根据角色创建
host或client链路 - 管理
DataChannel生命周期 - 提供
send / broadcast / request / kick - 处理心跳、ACK、请求响应、重连等基础能力
3. 信令适配层
connect/adapters/PeerJSSignalAdapter.jsconnect/adapters/NativeSignalAdapter.jsconnect/adapters/SignalAdapterBase.jsconnect/adapters/NativeDataConnection.js
职责是:
- 负责建连前的信令交换
- 对上层输出统一
DataConnection接口 - 屏蔽
PeerJS与原生RTCPeerConnection的差异
4. 数据同步层
data/DataCore.jsdata/ReplicationManager.jsdata/KeyValueStore.jsdata/ListStore.jsdata/MapStore.jsdata/StorageDriver.js
职责是:
- 基于通讯核心做房间数据同步
- Host 作为权威数据源
- Client 通过 patch 或 snapshot 跟随同步
- 支持
kv / list / map三种命名空间数据容器
基础用法
推荐把“低频基础配置”和“高频业务参数”分开:
configure():保存不常变化的基础配置,例如信令地址、ICE 配置、重连策略connect():传入每次连接都可能变化的参数,例如role、roomId
1. 导入
import jzWebrtcConnect from '@/uni_modules/jz-webrtc-connect/js_sdk/jz-webrtc-connect'
2. 初始化基础配置
await jzWebrtcConnect.configure({
signal: {
adapter: 'peerjs',
peerjs: {
host: 'peer.example.com',
port: 443,
path: '/peerjs',
secure: true
}
},
rtcConfig: {
iceServers: [
{ urls: 'stun:stun.qq.com:3478' },
{ urls: 'stun:stun.aliyun.com:3478' }
]
},
reconnect: {
enabled: true,
maxAttempts: 5,
baseDelayMs: 1000,
factor: 2,
maxDelayMs: 16000
}
})
3. Host 创建房间
const core = await jzWebrtcConnect.connect({
role: 'host',
roomId: 'room-001'
})
core.on('ready', event => {
console.log('host ready', event.peerId)
})
core.on('peer-join', event => {
console.log('peer joined', event.peerId)
})
core.on('message', event => {
console.log('message', event)
})
4. Client 加入房间
const core = await jzWebrtcConnect.connect({
role: 'client',
roomId: 'room-001'
})
core.on('ready', event => {
console.log('client ready', event.peerId)
})
消息发送用法
1. 单播消息
await core.send('peer-xxx', 'chat', {
type: 'text',
payload: { text: 'hello' }
})
如果你不想自己写 type / payload 结构,也可以直接传业务对象:
await core.send('peer-xxx', 'chat', { text: 'hello' })
这时内部会自动转成:
{ type: 'msg', payload: { text: 'hello' } }
2. ACK 确认
const result = await core.send('peer-xxx', 'chat', { text: 'need ack' }, {
ack: true,
timeoutMs: 5000
})
console.log(result.acked)
3. Host 广播
只有 host 可以调用 broadcast():
await core.broadcast('room', {
type: 'notice',
payload: { text: 'game start' }
})
4. 请求响应
发起方:
const result = await core.request('peer-xxx', 'biz', {
action: 'get-profile'
})
console.log(result)
接收方:
core.on('request', event => {
if (event.channel !== 'biz') return
event.respond({
id: 1,
name: 'demo-user'
})
})
数据同步层用法
如果你不只是收发消息,还希望同步一份房间内共享数据,可以创建 DataCore。
const core = await jzWebrtcConnect.connect({
role: 'host',
roomId: 'room-001'
})
const data = jzWebrtcConnect.createDataCore({ core })
const roomStore = data.namespace('room', 'kv')
roomStore.set('status', 'open')
roomStore.set('round', 1)
支持的数据容器
kv:键值对象,适合房间状态、配置项list:列表容器,适合成员队列、聊天记录map:映射容器,适合按主键存储复杂结构
可选持久化
默认使用内存驱动,也可以切换为 UniStorageDriver:
import jzWebrtcConnect, { UniStorageDriver } from '@/uni_modules/jz-webrtc-connect/js_sdk/jz-webrtc-connect'
const data = jzWebrtcConnect.createDataCore({ core, autoPersist: true })
data.use(new UniStorageDriver('demo-room:'))
配置项说明
下面按实际源码能力说明常用配置项。
configure(baseConfig)
低频基础配置,内部只缓存,不会立即建连。
connect(sessionConfig)
会把 sessionConfig 与此前 configure() 的配置做合并,然后真正创建连接。
顶层配置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
role |
'host' \| 'client' |
无 | 必填,当前节点角色 |
roomId |
string |
无 | 房间 ID;peerjs 模式下 Host 默认会把它作为 peerId |
peerId |
string |
自动生成或由适配器生成 | 当前节点自定义 ID |
hostPeerId |
string |
roomId |
Client 连接的 Host peerId;不传时通常回退到 roomId |
maxClients |
number |
8 |
Host 最大接入人数 |
handshakeTimeoutMs |
number |
15000 |
DataChannel 握手超时毫秒数 |
heartbeatIntervalMs |
number |
5000 |
心跳发送间隔 |
heartbeatMissThreshold |
number |
3 |
连续丢失多少次心跳判定离线 |
codec |
string |
'json' |
消息编解码方式 |
rtcConfig |
RTCConfiguration |
{} |
WebRTC ICE 配置 |
reconnect |
object |
见下文 | Client 重连策略 |
relay |
object |
{ enabled: true, includeSender: true } |
Host 是否把客户端消息继续转发给房间其他成员 |
signal |
object |
{ adapter: 'peerjs' } |
信令适配器配置 |
rtcConfig
这是 WebRTC 能否成功直连的关键配置之一,通常至少需要配置 iceServers:
rtcConfig: {
iceServers: [
{ urls: 'stun:stun.qq.com:3478' },
{ urls: 'stun:stun.aliyun.com:3478' },
{
urls: 'turn:turn.example.com:3478',
username: 'demo',
credential: 'demo-password'
}
]
}
说明:
- STUN 用于探测公网候选地址,帮助打洞
- TURN 用于复杂网络下的中继兜底
- 如果你非常强调“打洞成功后不走服务器”,就必须重视 STUN/TURN 配置质量
- 公共 STUN 仅适合测试,生产环境建议自建或购买稳定 TURN 服务
reconnect
仅客户端侧有效:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled |
boolean |
true |
Host 断开后是否自动重连 |
maxAttempts |
number |
5 |
最大重试次数 |
baseDelayMs |
number |
1000 |
首次重连延迟 |
factor |
number |
2 |
指数退避倍数 |
maxDelayMs |
number |
16000 |
最大重连延迟 |
relay
Host 收到客户端业务消息后,可继续通过 WebRTC 数据通道转发给房间其他客户端:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled |
boolean |
true |
是否开启消息转发 |
includeSender |
boolean |
true |
转发时是否包含原发送者 |
注意:
- 这里的“转发”发生在房主节点
host上 - 它依然不经过中心业务服务器
- 适合一个房主带多个成员的房间式架构
signal 配置说明
1. peerjs 模式
适合:
- 希望快速接入
- 已有 PeerServer
- 不想自己处理
offer / answer / candidate
示例:
await jzWebrtcConnect.configure({
signal: {
adapter: 'peerjs',
peerjs: {
host: 'peer.example.com',
port: 443,
path: '/peerjs',
secure: true
}
},
rtcConfig: {
iceServers: [{ urls: 'stun:stun.qq.com:3478' }]
}
})
signal.peerjs 会透传给 PeerJS 构造配置,常见字段包括:
| 配置项 | 说明 |
|---|---|
host |
PeerServer 域名或 IP |
port |
PeerServer 端口 |
path |
PeerServer 路径 |
secure |
是否使用 HTTPS / WSS |
| 其他 PeerJS 支持字段 | 会一起透传给 PeerJS |
说明:
- PeerJS 负责的是信令和 DataConnection 封装
- WebRTC 的 STUN / TURN 仍然由
rtcConfig决定 - Host 若未手动传
peerId,默认会优先使用roomId
2. native 模式
适合:
- 自己掌控信令服务器
- 希望完全使用原生
RTCPeerConnection - 想把信令与业务数据彻底分离
示例:
await jzWebrtcConnect.configure({
signal: {
adapter: 'native',
native: {
url: 'wss://signal.example.com/ws',
token: 'login-token'
}
},
rtcConfig: {
iceServers: [
{ urls: 'stun:stun.qq.com:3478' },
{ urls: 'stun:stun.aliyun.com:3478' }
]
}
})
const core = await jzWebrtcConnect.connect({
role: 'client',
roomId: 'room-001'
})
signal.native 配置项:
| 配置项 | 类型 | 说明 |
|---|---|---|
url |
string |
WebSocket 信令服务地址 |
token |
string |
可选认证字段,发送信令时会自动附带 |
transport |
object |
自定义传输对象,优先级高于 url |
hostPeerId |
string |
可选,Client 未显式传远端时的默认 Host peerId |
native 模式服务端需要做什么
服务端逻辑非常轻:
- 按
roomId区分房间 - 按
to定向转发信令包 - 无需理解 SDP 内容
- 无需转发业务数据
插件内部会处理的信令类型包括:
host-readyjoinofferanswercandidateleave
也就是说,WebSocket 在这个架构中主要只是“建连协调员”,不是“业务转发通道”。
自定义 transport 接口
如果不想直接使用默认 WebSocket,可以传一个自定义对象,插件会按下面的最小接口调用:
const transport = {
async connect() {},
onMessage(handler) {},
send(payload) {},
close() {}
}
3. custom 模式
适合:
- 你已经有自己的信令适配器
- 你希望复用插件上层的
ConnectCore / PeerLink / DataCore
示例:
import jzWebrtcConnect, { SignalAdapterBase } from '@/uni_modules/jz-webrtc-connect/js_sdk/jz-webrtc-connect'
class MySignalAdapter extends SignalAdapterBase {
async init() {
this.peerId = 'custom-peer-id'
return this.peerId
}
connect(remotePeerId) {
return createYourOwnDataConnection(remotePeerId)
}
}
await jzWebrtcConnect.configure({
signal: {
adapter: 'custom',
custom: new MySignalAdapter()
}
})
自定义适配器最少需要实现:
init()connect(remotePeerId)onIncoming(handler)onDisconnected(handler)onError(handler)destroy()
事件说明
ConnectCore 常用事件:
| 事件名 | 说明 |
|---|---|
ready |
当前节点初始化完成 |
peer-join |
有远端节点接入 |
peer-leave |
有远端节点离开 |
message |
收到普通消息 |
request |
收到 RPC 请求 |
error |
连接或编解码相关错误 |
state-change |
核心状态变化 |
reconnect-attempt |
客户端开始重连 |
reconnect-success |
客户端重连成功 |
reconnect-fail |
客户端重连失败 |
常见监听方式:
core.on('peer-join', event => {
console.log(event.peerId, event.role)
})
core.on('peer-leave', event => {
console.log(event.peerId, event.code, event.reason)
})
core.on('error', event => {
console.error(event.code, event.message)
})
实际工作流程
以 native + WebSocket 信令 为例,完整链路通常是:
- Host 连接 WebSocket 信令服务,发送
host-ready - Client 连接同一个信令服务并发送
join - 双方通过 WebSocket 交换
offer / answer / candidate - WebRTC 尝试打洞,建立
RTCPeerConnection DataChannel打开后,业务消息开始直连传输- 后续高频数据不再依赖信令服务器
这就是这个插件最值得强调的价值点:
- WebSocket 只承担建连阶段和必要控制面通信
- 高频业务数据尽量走终端直连
- 打洞成功后,服务器资源消耗远小于纯 WebSocket 实时转发方案
适合怎么设计业务
推荐把架构拆成两层:
- 低频控制层:登录、鉴权、房间匹配、信令准备
- 高频数据层:通过
jz-webrtc-connect走 WebRTCDataChannel
这种设计相较于“所有实时数据全部走 WebSocket”更适合:
- 房间内消息频率高
- 服务端不想承受持续中转压力
- 对实时性和成本更敏感
常见注意事项
- 插件只负责通讯能力,不负责业务 UI
- Host / Client 的连接拓扑是“房主中心化房间模型”,不是全量 mesh
broadcast()仅 Host 可用kick()仅 Host 可用DataCore不是必需模块,只做消息收发可不创建- 生产环境请认真配置 STUN / TURN,不要只依赖公共 STUN
- 如果业务极度依赖“完全不走服务器”,需要接受部分网络环境下可能退化到 TURN 的现实
总结
jz-webrtc-connect 的核心价值,不只是“能建 WebRTC 连接”,而是:
- 用统一 API 屏蔽
PeerJS / native / custom差异 - 把高频业务流量从中心服务器转移到终端之间
- 在打洞成功时实现“业务数据不走服务器”的资源节约效果
- 让
uni-app项目可以更清晰地构建“低频信令 + 高频点对点数据”的实时架构

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 2408
赞赏 0
下载 12286069
赞赏 1922
赞赏
京公网安备:11010802035340号