RWI 协议参考

RWI(实时 WebSocket 接口) 是 RustPBX 面向外部软件的控制面:通过单个 WebSocket 承载命令/事件协议,并为非交互式消费方提供 HTTP Webhook 桥。本页是协议参考;Webhook 配置见对应页面。

1. 传输与认证

项目说明
协议WebSocket(生产环境使用 WSS)
方向全双工——命令发出,事件在同一有序通道返回
认证控制台会话、坐席令牌,或部署配置的 API Token
范围一个 socket 连接代表一个已认证主体

一个客户端一条 socket 是推荐模式。主体范围内的事件会自动到达,无需轮询,也不需要逐通订阅。

2. 事件模型

每个呼叫范围内的事件都携带根通话标识块,子腿可归并为一通逻辑通话:

字段含义
call_id事件所属的腿
session_id逻辑通话的根会话(根腿时等于 call_id)
directioninbound / outbound
src_ip / client_ip多租户与安全过滤所需的归因信息

Event categories

CategoryExamples
通话生命周期call_created、call_ringing、call_answered、call_hangup
通话错误统一 call_error,含错误目录引用
媒体call_early_media、录音起停、播放完成
DTMF / IVRdtmf、ivr_step_trace、流程 resume
队列 / ACDqueue_joined、queue_agent_connected、overflow_joined、dequeued
坐席状态迁移、整理起止、小休变更
会话数据user_data 更新、呼叫变量变更
集群会话归属变更、对端存活

事件示例

{
  "event": "call_answered",
  "call_id": "d3f0-…@10.0.0.1",
  "session_id": "d3f0-…@10.0.0.1",
  "direction": "inbound",
  "caller": "8613800001001",
  "callee": "1001",
  "agent_id": "demo-agent-alice",
  "queue_id": "demo-support-tier1",
  "src_ip": "203.0.113.20",
  "client_ip": "198.51.100.7",
  "timestamp": "2026-10-04T09:12:03.482Z"
}

根腿的 session_id 等于 call_id;子腿(队列派单、转接)携带相同的 session_id,消费方据此归组。

顺序与投递

  • 同一会话的事件按归属节点的观测顺序排列。
  • Webhook 投递为至少一次,幂等键在重试间保持不变,消费方据此去重。
  • rwi_event_queue_latency_seconds 直方图(可选开启)跟踪网关→处理器的排队延迟。

3. 命令模型

命令是带 command 字段的 JSON 消息,能力与平台对齐:

分组命令
呼叫控制originate、answer、hangup、bridge、transfer(盲转/咨询)、hold、resume
媒体play(支持 side_only)、send_dtmf(rfc4733 / SIP INFO)、app.stop
会话数据set_userdata / get_userdata、set_var / get_var
队列入队 / 出队、坐席分配、优先级更新
会议创建房间、加入/移除参与者、结束房间

REST 等价接口

交互式命令在 /api 下有对应的 REST 接口,便于脚本化:

操作端点
列出活动通话GET /api/calls/active
查看会话GET /api/calls/active/{session_id}
发送命令POST /api/calls/active/{session_id}/commands
读写用户数据GET / PUT /api/calls/active/{session_id}/userdata
强制挂断GET /ami/v1/hangup/{id}

命令示例

{
  "command": "transfer",
  "session_id": "d3f0-…@10.0.0.1",
  "type": "attended",
  "target": "1002",
  "request_id": "req-7f31"
}

响应回显 request_id;结果也以事件形式在同一 socket 返回,客户端无需轮询即可关联「命令 → 结果」。

4. 会话用户数据

用户数据是挂在会话上的应用状态——CRM 工单号、营销活动标签、坐席上下文。规则:

  • 任意时刻可写,任意节点可读
  • 复制到对端节点
  • 被子会话与队列派单继承
  • 可从 RWI socket 与上述 REST 端点访问
  • 在线路上,逐键 X-<key> SIP 头把扁平视图带给主被叫腿(聚合的 X-User-Data 形态已废止)

5. 集群行为

集群中,所连节点未必持有该通话。协议对此透明:

行为说明
归属路由命令透明转发到归属节点
信封/cluster/session_op(终端节点本地执行)
会话操作set_userdata / set_var 同样按归属路由
归属查询GET /cluster/session_owner/{call_id}
集群列举GET /cluster/list_calls
故障归属节点失效时其会话标记为 offline,而不是变成幽灵会话

6. Webhook 桥

对不持有 socket 的消费方,同样的事件经 HTTP 投递:

[rwi_webhook]
url = "https://your-server.example.com/api/rwi/events"
events = ["call_hangup", "call_error", "queue_agent_connected"]
retries = 3
  • 独立 worker 线程:慢速接收端不会拖垮通话
  • 传输错误、5xx、429 按指数退避重试
  • 幂等键在重试间一致,请求体逐字节相同
  • 配置支持热更新

7. 集成模式

  1. 连接 socket、完成认证,自动获得主体范围内的事件
  2. 维护以 session_id 为键的本地映射
  3. 在应答时通过 set_userdata 附加业务上下文
  4. 用同一 socket 下发控制命令;批处理任务走 REST
  5. 被动消费方走 Webhook,按幂等键去重
  6. 集群环境下依赖归属路由——不要假设本地节点持有通话

另见:RWI 事件与 Webhook及可扩展性指南。