夜雨聆风学习资料网

ARTICLE · 1029486

dtnsbot API 更新说明(整合dtns.rpc-fast之e2ee和NAT内网穿透通讯能力)

dtnsbot API 更新说明(整合dtns.rpc-fast之e2ee和NAT内网穿透通讯能力)

dtnsbot API 更新说明(整合dtns.rpc-fast之e2ee和NAT内网穿透通讯能力)

dtns.rpc-fast 技术整合公告

版本:v2.0(WebRTC RPC) 发布日期:2026-09-18 影响范围:新增 WebRTC RPC 通道,HTTP API 完全兼容,无需改动


一、更新摘要

dtnsbot 在保持原有 HTTP API(http://[设备IP]:58082/api/?command=...)不变的前提下,新增了基于 WebRTC 的 RPC 通道。这项能力的核心是集成了 dtns.rpc-fast 技术栈,使得:

  • 所有 HTTP 命令
    都可以通过 WebRTC 调用,命令语义完全一致
  • 文件传输
    从"Base64 over HTTP"升级为"二进制分片 over WebRTC",支持 GB 级文件
  • NAT 穿透
    无需公网 IP、无需端口映射,跨网络直连
  • 断点续传 / 动态切片 / 服务端驱动重发
    网络抖动下自动恢复
  • 大 JSON 自动 gzip 压缩
    带宽节省最高 90%

HTTP API 用户无需任何改动,可直接继续使用。


二、为什么要整合 dtns.rpc-fast

2.1 原有 HTTP API 的局限

局限
影响
需要公网 IP / 端口映射
设备在 4G/5G/内网时无法被外部访问
文件走 Base64
传输体积膨胀 33%,CPU 编解码开销大
单次请求 body 限制
大文件(>100MB)传输不可靠
无进度、无断点续传
网络抖动即失败,需重传整个文件
大 JSON 无压缩
大结果直接占用带宽,慢且占内存

2.2 dtns.rpc-fast 带来的能力

能力
说明
P2P NAT 穿透
局域网/跨网直连,无需公网 IP
二进制分片传输
无 Base64 膨胀,接近原生吞吐
GB 级文件支持
分片 + ACK + 滑动窗口
断点续传streamId
 持久化,重连后继续
动态切片
32KB → 512KB 自适应网络质量
服务端驱动重发STREAM_RETRY
 精确重传丢包分片
大 JSON gzip 压缩
自动压缩,节省带宽与内存
E2EE 传输加密
DTLS-SRTP 强制加密

三、dtns.rpc-fast 技术架构

3.1 整体分层

┌─────────────────────────────────────────────────────────┐│  应用层:dtnsbot 命令处理(onCommandReceived)            │├─────────────────────────────────────────────────────────┤│  协议层:dtns.rpc-fast                                    ││    - RPC 帧:REQ / RES / ERR / STREAM / ACK / RETRY       ││    - 分片:动态切片 + 滑动窗口 + 停滞检测                 ││    - 存储抽象:sink / source 接口                         │├─────────────────────────────────────────────────────────┤│  传输层:WebRTC DataChannel (SCTP over DTLS)             ││    - 强制加密 (DTLS-SRTP)                                 ││    - 可靠传输 (SCTP ordered mode)                         ││    - NAT 穿透 (STUN/TURN/ICE)                             │├─────────────────────────────────────────────────────────┤│  信令层:Socket.IO + simple-signal                        ││    - SDP / ICE 交换                                       ││    - 房间发现                                             │└─────────────────────────────────────────────────────────┘

3.2 关键设计

① 上传当反向下载

上传和下载在协议层完全对称

方向
推送方 (Pusher)
接收方 (Receiver)
下载
(Server → Client)
Android
浏览器/Node
上传
(Client → Server)
浏览器/Node
Android

同一套 StreamPusher / StreamReceiver 类,角色互换即完成上传/下载。

② 动态切片

事件
动作
顺利(无重传)
切片 × 1.5
重传 ≥ 2 次
切片 ÷ 2
上下限
16KB ~ 512KB

③ 服务端驱动重发

  • Android 端检测到坏片/丢片 → 主动发 STREAM_RETRY
  • 客户端只重发对应分片,其他不动
  • 停滞 5 秒无进展 → 主动要求重发下一片

④ 大 JSON 自动降级 + 压缩

结果 JSON ≤ 16KB        → RES 直接返回结果 JSON > 16KB        → gzip (JSZip) → 走 stream 通道结果 JSON > 256MB       → 报错(避免 OOM)

⑤ 存储抽象

  • Android
    AndroidDownloadSink → JS 桥接 Java RandomAccessFile
  • 浏览器
    OpfsDownloadSink → OPFS(Origin Private File System)
  • Node
    FsDownloadSink → fs.writeSync
  • 内存
    MemoryDownloadSink → 兜底

四、新增 API 概览

4.1 WebRTC 管理命令(HTTP 调用)

这些命令通过原有 HTTP API 调用,用于控制 WebRTC 行为:

命令
用途
webrtc_server_start
启动 WebRTC Server
webrtc_server_stop
停止 WebRTC Server
webrtc_client_start
启动 WebRTC Client
webrtc_client_stop
停止 WebRTC Client
webrtc_set_signal&url=...
设置信令服务器 URL
webrtc_set_server_room&room=...
设置 Server 房间号
webrtc_set_client_room&room=...
设置 Client 房间号
webrtc_status
查询 WebRTC 状态
webrtc_rpc_call&url=...&params=...
通过 Client 远程调用
webrtc_rpc_upload&url=...&path=...
通过 Client 远程上传
webrtc_rpc_download&url=...&params=...&save=...
通过 Client 远程下载

示例

# 配置信令curl "http://127.0.0.1:58082/api/?command=webrtc_set_signal&url=http://dev.dtns.top"# 配置 Server 房间curl "http://127.0.0.1:58082/api/?command=webrtc_set_server_room&room=room-android-001"# 启动 Servercurl "http://127.0.0.1:58082/api/?command=webrtc_server_start"# 查询状态curl "http://127.0.0.1:58082/api/?command=webrtc_status"

4.2 WebRTC RPC 通道

通过 WebRTC 连接后,可调用以下 RPC 接口:

RPC 接口
等价 HTTP
说明
/command/api/?command=...所有 HTTP 命令
/file/getfile_download
下载文件(二进制流)
/file/putfile_upload
上传文件(二进制流)
/file/listfile_list
列出文件

关键/command 内部调用同一个 onCommandReceived,因此 HTTP 命令全部自动可用

4.3 命令通道对照表

HTTP API
WebRTC RPC
GET /api/?command=homecall('/command', { command: 'home' })
GET /api/?command=click_at_500,800call('/command', { command: 'click_at_500,800' })
GET /api/?command=set_config&key=k&value=vcall('/command', { command: 'set_config', params: { key: 'k', value: 'v' } })
GET /api/?command=get_screenshot_direct&quality=60call('/command', { command: 'get_screenshot_direct', params: { quality: '60' } })
GET /api/?command=file_download&path=...download('/file/get', { path: '...' })
GET /api/?command=file_upload&...upload(file, '/file/put', { path: '...' })
GET /api/?command=file_list&path=...call('/file/list', { path: '...' })

五、使用示例

5.1 浏览器端接入

<script src="socket.io.min.js"></script><script src="simple-signal-client.min.js"></script><script src="jszip.min.js"></script><script src="rpc-protocol.js"></script><script src="rpc-core.js"></script><script src="opfs-utils.js"></script><script src="storage-browser.js"></script><script>const SSC = window.SimpleSignalClient || window.SimpleSignal;const client = new RPCCore.RPCClient(    'room-android-001',            // Android 端配的 room    'http://dev.dtns.top',         // 信令服务器    {},    {        socketIo: io,        SimpleSignalClient: SSC,        rtcOptions: {            iceServers: [                { urls: 'turn:static.dtns.top:3478' },                { urls: 'stun:stun.l.google.com:19302' },            ],        },        createDownloadSink: () => new BrowserStorage.OpfsDownloadSink({ dir: 'downloads' }),        wrapUploadSource: (src) => src instanceof Blob            ? new BrowserStorage.FileUploadSource(src)            : src,    });await client.connect();console.log('connected to Android');// 调用 HTTP 命令(与 /api/?command=home 等价)await client.call('/command', { command: 'home' });// 截图const shot = await client.call('/command', { command: 'get_screenshot_direct' });console.log(shot.data);   // base64// OCRconst ocr = await client.call('/command', { command: 'get_screenshot_ocr' });console.log(ocr.data.data.text);// 下载文件(二进制流,无 Base64)const dl = await client.download(    '/file/get',    { path: '/sdcard/Download/test.png', name: 'test.png' },    null,    (got, total) => console.log(`${got}/${total}`));console.log('saved:', dl.url);// 上传文件const file = fileInput.files[0];const up = await client.upload(    file,    '/file/put',    { path: '/sdcard/Download/', filename: file.name },    (acked, total) => console.log(`${acked}/${total}`));console.log('uploaded to:', up.path);// 列文件const list = await client.call('/file/list', { path: '/sdcard/Download' });console.log(list.files);</script>

5.2 Node.js 端接入

const io = require('socket.io-client');const SimpleSignalClient = require('simple-signal-client');const wrtc = require('wrtc');const { RPCClient } = require('./rpc-core.js');const { FsDownloadSink, FsUploadSource } = require('./storage-node.js');const client = new RPCClient('room-android-001', 'http://dev.dtns.top', {}, {    socketIo: io,    SimpleSignalClient,    rtcOptions: {        wrtc,        iceServers: [{ urls: 'turn:static.dtns.top:3478' }],    },});await client.connect();// 命令console.log(await client.call('/command', { command: 'screen_info' }));// 下载await client.download(    '/file/get',    { path: '/sdcard/Download/test.png' },    new FsDownloadSink({ savePath: './test.png' }));// 上传await client.upload(    new FsUploadSource('./test.png'),    '/file/put',    { path: '/sdcard/Download/' });

5.3 Android 作为 Client(反向连接)

# 1. 配置信令curl "http://127.0.0.1:58082/api/?command=webrtc_set_signal&url=http://dev.dtns.top"# 2. 配置要连接的目标房间curl "http://127.0.0.1:58082/api/?command=webrtc_set_client_room&room=room-clean-demo"# 3. 启动 Clientcurl "http://127.0.0.1:58082/api/?command=webrtc_client_start"# 4. 等待连接建立sleep 5# 5. 远程调用curl "http://127.0.0.1:58082/api/?command=webrtc_rpc_call&url=/command&params=%7B%22command%22%3A%22screen_info%22%7D"# 6. 远程上传curl "http://127.0.0.1:58082/api/?command=webrtc_rpc_upload&url=/file/put&path=/sdcard/test.png"# 7. 远程下载curl "http://127.0.0.1:58082/api/?command=webrtc_rpc_download&url=/file/get&params=%7B%22path%22%3A%22/remote/test.png%22%7D&save=/sdcard/test.png"

六、性能对比

6.1 HTTP vs WebRTC RPC

维度
HTTP API
WebRTC RPC
命令调用
单次请求
持久连接 + 多路复用
命令延迟
RTT + 请求开销
RTT(无请求开销)
文件传输
Base64 编码,膨胀 33%
二进制分片
大文件
不可靠
GB 级支持
断点续传
协议层支持
大 JSON
无压缩
gzip 压缩,最高省 90%
NAT 穿透
需公网 IP/端口映射
天然穿透
进度反馈
实时进度回调
加密
HTTPS(需证书)
DTLS-SRTP(强制)
E2EE
取决于部署
信令可信时成立

6.2 实测数据

  • 局域网下载 83MB
    HTTP 约 3-5 秒,WebRTC RPC 约 1-2 秒
  • 跨省下载 83MB
    HTTP 需公网 IP,WebRTC RPC 直连约 5-10 秒
  • 大 JSON 500KB
    HTTP 直接传,WebRTC RPC gzip 后约 30KB

:Android WebView 由于桥接开销,速度约为 Node.js 版的 1/10,但仍比 HTTP 快(无 Base64 膨胀)。


七、兼容性说明

7.1 完全向后兼容

  • HTTP API 保持不变
    所有原有命令、参数、返回格式、错误码完全一致
  • WebRTC 通道是新增能力
    不启用时不影响任何现有功能
  • 配置文件兼容
    新增字段可选,无强制要求

7.2 数据格式兼容

HTTP
WebRTC RPC
命令名
command=home{command: 'home'}
参数
query string
params: {...}
返回
JSON
JSON(结构一致)
错误
{status:'error', message}
同上
文件路径

同一份业务代码,两套 API 都能用

7.3 文件路径兼容

操作
默认路径
下载
优先 /sdcard/Download/,回退 App 私有目录
上传
优先 /sdcard/Download/,回退 App 私有目录
文件列表
默认 /sdcard/

与 HTTP 的 file_upload / file_download 默认路径一致


八、安全性与 E2EE

8.1 加密机制

WebRTC 强制加密,所有 DataChannel 走 DTLS-SRTP

  • 每个 Peer 生成自签名证书
  • SDP 里带 a=fingerprint(证书指纹)
  • 握手时校验指纹,防中间人
  • 媒体和 DataChannel 全部加密

8.2 是否 E2EE

场景
加密
E2EE
P2P 直连
✅ 是 E2EE
TURN 中继
✅ 是 E2EE(TURN 只转发密文)
信令被篡改
✅ 传输层
❌ 可被 MITM

关键信令服务器是信任锚

  • 信令走 HTTPS/WSS + 你自己控制的服务器
     → 达到 E2EE 级别
  • 信令被第三方控制
     → 需要额外验证(如 fingerprint 外带校验)

8.3 增强建议

  1. 确保信令走 HTTPS/WSS
    (默认配置已启用)
  2. 用自己控制的信令服务器
    (不使用公共信令)
  3. 可选
    :在 UI 上展示 fingerprint,让用户手动核对

九、部署建议

9.1 信令服务器

选项
适用场景
公共信令(dev.dtns.top
开发测试
自建 simple-signal-server
生产环境
内网信令
局域网部署

9.2 TURN 服务器

选项
适用场景
公共 TURN
快速上手
自建 coturn
生产环境
无 TURN(仅 STUN)
同网段/企业内网

9.3 Android 权限

WebRTC RPC 需要:

<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!-- 写 /sdcard/Download/ 需要 --><uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"    tools:ignore="ScopedStorage" />

不申请 MANAGE_EXTERNAL_STORAGE 时,文件默认保存到 App 私有目录(/storage/emulated/0/Android/data/com.example.dtnsbot/files/downloads/),无需任何权限


十、迁移指南

10.1 从 HTTP-only 迁移到 WebRTC RPC

步骤

  1. 部署信令服务器
    (或使用 dev.dtns.top
  2. Android 端配置
    webrtc_set_signal + webrtc_set_server_room
  3. 启动 Server
    webrtc_server_start
  4. 客户端引入 RPC 库
    rpc-core.js + 依赖
  5. 替换调用
    fetch('/api/?command=...') → client.call('/command', {...})

渐进式迁移

  • 先保留 HTTP
    WebRTC 作为补充
  • HTTP 用于
    简单命令、调试、脚本
  • WebRTC 用于
    大文件、跨 NAT、实时交互
  • 两者可共存
    不冲突

10.2 从 dtnsbot 旧版升级

升级步骤

  1. 更新 APK(v2.0+)
  2. 无需改动 HTTP 调用代码
  3. 配置文件自动兼容
  4. 如需 WebRTC:通过 HTTP 触发 webrtc_server_start

回滚

  • 禁用 WebRTC:webrtc_server_stop + webrtc_client_stop
  • HTTP API 不受影响

十一、常见问题

Q1:HTTP API 会被移除吗?

不会。HTTP API 是 dtnsbot 的核心能力,会长期保留。WebRTC RPC 是补充,不是替代。

Q2:什么时候用 HTTP,什么时候用 WebRTC?

场景
推荐
局域网、简单命令
HTTP
(简单)
跨 NAT、无公网 IP
WebRTC
(穿透)
大文件(>100MB)
WebRTC
(分片)
实时交互、进度反馈
WebRTC
(持久连接)
脚本、调试
HTTP
(curl 友好)

Q3:WebRTC 需要 TLS 证书吗?

不需要。WebRTC 自签名证书 + DTLS 自动加密。信令服务器(Socket.IO)需要 HTTPS/WSS,但这是服务器侧的事。

Q4:文件保存到哪里?

  • 优先/sdcard/Download/<原名>
    (需 MANAGE_EXTERNAL_STORAGE
  • 回退/storage/emulated/0/Android/data/com.example.dtnsbot/files/downloads/<原名>
  • 可通过 params.path 指定
    目标目录

Q5:WebRTC 比 HTTP 慢吗?

  • 命令调用
    WebRTC 略快(无 HTTP 请求开销)
  • 小文件
    WebRTC 略快(无 Base64 膨胀)
  • 大文件
    WebRTC 明显快(分片 + 断点续传 + 动态切片)
  • Android WebView
    由于桥接开销,速度约为 Node 版的 1/10

Q6:安全吗?

传输加密:✅ 强制 DTLS-SRTP。 E2EE:取决于信令可信度

  • 用自己的信令服务器 → E2EE 级别
  • 用公共信令 → 传输加密,但信令可 MITM

Q7:可以同时运行 Server 和 Client 吗?

可以。Android 设备可以同时作为 Server(被连接)和 Client(主动连接)。

Q8:能跨设备互联吗?

可以

  • Android ↔ 浏览器
  • Android ↔ Node
  • Android ↔ Android
  • 浏览器 ↔ Node

只要它们用同一套 rpc-protocol.js + rpc-core.js


十二、技术栈与文件清单

12.1 核心文件

文件
作用
rpc-protocol.js
协议层(帧编解码)
rpc-core.js
协议核心(Pusher/Receiver/Client/Server)
storage-android.js
Android 存储实现
storage-browser.js
浏览器存储实现
storage-node.js
Node 存储实现
opfs-utils.js
OPFS 工具(浏览器)
rpc-bridge.html
Android WebView 宿主
WebrtcRpcManager.kt
Kotlin 桥接管理

12.2 依赖

依赖
作用
socket.io-client
信令 WebSocket
simple-signal-client
WebRTC 信令封装
jszip
大 JSON gzip 压缩
wrtc
(Node)
Node 端 WebRTC 实现

十三、后续计划

13.1 短期(v2.1)

  • fingerprint 外带校验
    UI 展示证书指纹,用户手动核对,防信令 MITM
  • 断点续传持久化
    streamId 存 OPFS,App 重启后继续
  • 性能优化
    Android WebView 用 WebMessagePort 传 ArrayBuffer(去掉 Base64)

13.2 中期(v2.2)

  • 多连接管理
    一个 Android 同时连多个 Client
  • 文件树 API
    递归列目录、目录创建
  • 批量操作
    批量上传/下载/删除

13.3 长期(v3.0)

  • Signal Protocol 集成
    信令不可信下的强 E2EE
  • Android Native WebRTC
    替换 WebView,性能追平 Node
  • 信令服务器内嵌
    Android 自带信令,完全自包含

十四、总结

维度
整合前
整合后
命令调用
HTTP only
HTTP + WebRTC RPC
文件传输
Base64 over HTTP
二进制分片 over WebRTC
NAT 穿透
❌ 需公网 IP
✅ 天然穿透
大文件
❌ 不可靠
✅ GB 级支持
断点续传
进度反馈
大 JSON
❌ 无压缩
✅ gzip 压缩
加密
HTTPS(需证书)
DTLS-SRTP(强制)
兼容性
✅ HTTP API 完全不变

核心价值

dtns.rpc-fast 的整合,让 dtnsbot 从"HTTP-only 的局域网工具"升级为"支持 NAT 穿透、大文件传输、实时交互的分布式 RPC 平台",同时保持对原有 HTTP API 的完全兼容


附录:快速上手

# ===== Android 端 =====# 1. 配置信令curl "http://127.0.0.1:58082/api/?command=webrtc_set_signal&url=http://dev.dtns.top"# 2. 配置房间curl "http://127.0.0.1:58082/api/?command=webrtc_set_server_room&room=room-android-001"# 3. 启动 Servercurl "http://127.0.0.1:58082/api/?command=webrtc_server_start"# 4. 查看状态curl "http://127.0.0.1:58082/api/?command=webrtc_status"# ===== 浏览器端 =====# 1. 引入依赖<script src="socket.io.min.js"></script><script src="simple-signal-client.min.js"></script><script src="jszip.min.js"></script><script src="rpc-protocol.js"></script><script src="rpc-core.js"></script><script src="opfs-utils.js"></script><script src="storage-browser.js"></script># 2. 连接const client = new RPCCore.RPCClient('room-android-001', 'http://dev.dtns.top', {}, {    socketIo: io,    SimpleSignalClient: window.SimpleSignalClient,    rtcOptions: { iceServers: [{ urls: 'turn:static.dtns.top:3478' }] },    createDownloadSink: () => new BrowserStorage.OpfsDownloadSink({ dir: 'downloads' }),    wrapUploadSource: (src) => src instanceof Blob        ? new BrowserStorage.FileUploadSource(src)        : src,});await client.connect();# 3. 调用命令await client.call('/command', { command: 'home' });# 4. 下载文件const dl = await client.download('/file/get', { path: '/sdcard/Download/test.png' });# 5. 上传文件await client.upload(file, '/file/put', { path: '/sdcard/Download/' });

文档版本:v2.0 最后更新:2026-09-18 维护者:dtnsbot 团队 相关文档

  • dtnsbot-skill.md
    (HTTP API 主文档) skill文档:https://skills.html.dtns.top/dtnsbot-skill.html (底部带有新的webrtc通讯文档)
  • dtns.rpc-fast
     技术白皮书(待发布) 体验链接:http://web3.dtns.top/dtns.rpc-fast/dtnsbot-rpc-client.html

相关学习资料

返回首页浏览学习资料