通话控制
呼叫
RustPBX 支持 SIP 和 WebRTC 两种通话方式,在连接 RustPBX 时通过路径区分:
/call/sip: 使用 SIP 协议建立通话,RTP 传输音频。/call/webrtc: 直接使用 SDP Offer 建立通话。
使用 Invite 命令发起呼叫。 当通话建立成功会收到 Answer 事件, 否则会收到 Reject 事件。
呼叫和接听都使用 CallOption, 除设置被叫地址外,其他参数相同, 主要用于配置以下功能:
SIP 呼叫
SIP 呼叫需要在 CallOption 中设置主叫(caller)和被叫(callee) 的 SIP 地址,例:
{
"command": "invite",
"option": {
"caller": "sip:6001@192.168.1.100",
"callee": "sip:6002@192.168.1.100"
}
}
caller 地址可以设置为 UserAgent 的 SIP 地址, 默认为 sip:{本机IP}:13050。
UserAgent 的 SIP 地址可以在 config.toml 中配置:
[ua]
addr = "0.0.0.0"
udp_port = 13050 # 避免使用 5060
UserAgent 相当于一个话机,因此他有自己的 SIP 地址。
WebRTC 呼叫
WebRTC 呼叫需要在 option.offer 字段中设置呼叫目标的 SDP Offer,例如:
{
"command": "invite",
"option": {
"offer": "v=0\r\no=- 123456789 2 IN IP4 127.0.0.1\r\n..."
}
}
接听/拒绝
接听比呼叫略微复杂,需要配置 Webhook 接收来电通知。有以下几个步骤:
- 配置 Webhook
- 当有来电时,RustPBX 会向 Webhook 地址发送请求
- WebHook 服务根据请求中的
dialogId连接 RustPBX - 发送
Accept命令接听,或者Reject命令拒绝
配置 Webhook
在 config.toml 中配置 Webhook 地址:
[ua.handler]
type = "webhook"
url = "http://localhost:8090/webhook"
method = "POST"
接收通知
当有电话呼入时,RustPBX 会向 Webhook 地址发送 POST 请求, 例:
{
"event": "invite",
"dialogId": "9zUPiixVNO-xRTf4NqCV-dv9qE2iB",
"caller": "sip:6001@192.168.139.103",
"callee": "sip:192.168.3.197",
"createdAt": "2025-10-23T06:33:26.623706+00:00"
}
dialogId 格式为: {call_id}-{tag1}-{tag2}, 其中 tag1 为 from_tag 和 to_tag 中的字典序较大者,tag2 为较小者。
连接 RustPBX
使用 dialogId 作为 id 参数的值,建立 WebSocket 连接
'ws://localhost:8080/call/sip?id=9zUPiixVNO-xRTf4NqCV-dv9qE2iB'
接听/拒绝
然后发送 Accept (接听) / Reject (拒绝) 命令 :
示例代码:
在 RustPBX Go SDK 中有 webhook 示例代码,可以参考:
func serveWebhook(parent context.Context, option CreateClientOption, addr, prefix string) {
server := gin.Default()
server.POST(prefix, func(c *gin.Context) {
var form IncomingCall
if err := c.ShouldBindJSON(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
client := createClient(parent, option, form.DialogID)
go func() {
ctx, cancel := context.WithCancel(parent)
defer cancel()
err := client.Connect("sip")
if err != nil {
option.Logger.Errorf("Failed to connect to server: %v", err)
}
defer client.Shutdown()
client.Accept(option.CallOption)
time.Sleep(300 * time.Millisecond)
client.TTS(option.Greeting, "", "", true, false, nil, nil, false)
<-ctx.Done()
}()
c.JSON(200, gin.H{"message": "OK"})
})
server.Run(addr)
}
参阅 RustPBX Go SDK 获取更多信息。
转接
在通话中使用 Refer 命令可以将通话转接到另一个号码,用于"转人工"场景。
转接流程:
- 通话已经建立, 发送
Refer命令 - RustPBX 呼叫转接目标
- 目标接听后,RustPBX 互相转发两端音频
挂断
在通话建立后,使用 Hangup 命令挂断通话。示例:
{
"command": "hangup",
"reason": "Normal clearing"
}
事件
在通话的建立到结束整个过程中,会触发多种事件,如图示:
TrackStart
创建 RTP/WebRTC Track
Ringing
响铃事件, 对方已经收到呼叫,还未接听。
Answer
通话建立,对方已经接听。
Reject
对方拒绝,或其他 4xx 异常。
请求失败响应码列表: Request Failure 4xx
Hangup
通话建立后,对方挂断。
TrackEnd
RTP/WebRTC Track 结束。
TTS/Play 命令也会创建对应的 Track, 同样也会触发 TrackStart 和 TrackEnd 事件。可以用 TrackId 区分。
参见:TTS/Play。
其他事件
ASR 和 VAD 功能会触发相应的事件,包括:
- AsrDelta: 中间识别结果,内容可能会变动。
- AsrFinal: 最终识别结果,内容稳定。
- Speaking: 语音活动检测,有语音输入。
- Silence: 语音活动检测,一段时间没有语音输入。
📄️ CallOption 参数
CallOption 参数详细介绍