外观
FreeSWITCH 业务集成、拨号计划与录音托管专题
本文详细介绍 FreeSWITCH 与平台后端业务系统的对接配置,包括 Event Socket Layer (ESL) 通信机制、Dialplan 拨号计划路由至 callflow-esl、RTP 端口规划与防火墙、WebRTC WSS 证书以及 Nginx 通话录音托管服务。
1. ESL (Event Socket Layer) 安全与对接配置
配置文件路径:freeswitch-install/etc/freeswitch/autoload_configs/event_socket.conf.xml
FreeSWITCH 的 Inbound ESL 允许外部管理端(如 apps/callflow-esl 的管理客户端或监控组件)连接到 FreeSWITCH 端口并执行控制命令与事件订阅。
xml
<configuration name="event_socket.conf" description="Socket Client">
<settings>
<param name="nat-map" value="false"/>
<!-- 监听地址::: 表示 IPv4/IPv6 双栈监听;也可填 0.0.0.0 或 127.0.0.1 -->
<param name="listen-ip" value="::"/>
<!-- ESL 端口:默认 8021 -->
<param name="listen-port" value="8021"/>
<!-- ESL 认证密码:默认 ClueCon,生产环境必须修改为强密码 -->
<param name="password" value="ClueCon"/>
<!-- ACL 访问控制:建议生产环境开启 ACL 仅允许 callflow-esl 所在主机 IP 访问 -->
<!-- <param name="apply-inbound-acl" value="lan"/> -->
</settings>
</configuration>联调注意:修改此处的
password或listen-port后,必须同步修改apps/callflow-esl/config.toml中的freeswitch.password和freeswitch.port。
2. Outbound ESL 业务编排与拨号计划路由
当用户呼入指定业务号码(如 5000~5099)或外呼接通后,FreeSWITCH 需要通过 Outbound ESL 将控制权交由 callflow-esl 业务服务接管。
2.1 内部呼叫路由 (freeswitch-install/etc/freeswitch/dialplan/default.xml)
在 <context name="default"> 顶部已预置 AI 语音接入路由:
xml
<!--
【AI 语音呼叫流程接入 (Outbound ESL)】
当分机拨打 50 开头的号码时,将通话无缝送入 callflow-esl 业务层接管,执行智能语音导航与流式交互。
-->
<extension name="callflow-esl-socket">
<condition field="destination_number" expression="^50">
<!-- 使用 vars.xml 中的全局解耦宏变量 $${esl_host},避免硬编码 -->
<action application="socket" data="$${esl_host} async full"/>
</condition>
</extension>2.2 公网/中继呼入路由 (freeswitch-install/etc/freeswitch/dialplan/public/00_inbound_did.xml)
外部 DID 呼入进入 public 上下文后,优先匹配进线路由:
xml
<!-- 外部运营商 DID 呼入触发 AI 流程 (00_inbound_did.xml) -->
<extension name="public_esl_50">
<condition field="destination_number" expression="^50">
<!-- 关键参数: 通道空闲时持续发送静音 RTP 包,防 NAT / 运营商防火墙丢包超时 -->
<action application="set" data="send_silence_when_idle=-1"/>
<!-- 建立 Outbound ESL 异步连接,交由业务中台接管调度 -->
<action application="socket" data="$${esl_host} async full"/>
</condition>
</extension>2.3 send_silence_when_idle=-1 底层机制与防丢包原理深度解析 ⭐️
在实时 AI 语音通话(如大模型智能客服或外呼机器人)中,通话流程中存在数个典型的下行音频空白期:
- LLM 思考推理期:用户说话完毕触发 VAD 断句后,LLM 大模型思考、检索知识库并生成首句回答往往需要 0.3 ~ 1.5 秒;
- 等待用户发言期:播报完引导话术后,机器人等待用户做出回应的时间;
- 流程节点跳转与外部 API 查询期:ESL 业务逻辑执行数据库写入或调用第三方 HTTP 接口。
⚠️ 没有开启静音保持时的生产风险
如果通道在上述阶段没有下发任何音频,FreeSWITCH 默认会完全停止发送下行 RTP UDP 报文:
- NAT 端口老化被关:大多数云厂商 NAT 网关、运营商 SBC、以及客户端路由器对 UDP 连接的会话老化淘汰时间(UDP Session Aging Timeout)极为严格(通常仅 30 ~ 60 秒,某些特定专线甚至仅 15 秒)。一旦无包发送,NAT 会话表项立即被网关清除;
- 下行断音与丢包:随后当 TTS 生成完毕下发音频时,首批 RTP 包因无法穿越已被释放的 NAT 映射而直接被丢弃,导致用户听到吞字、声音爆卡或单通;
- 运营商异常拆线:运营商 IMS 核心网或企业级 SBC 普遍内置了严苛的 RTP 媒体无包探测看门狗(RTP Timeout Watchdog),连续数秒无 RTP 流量会直接判定呼叫异常断死,主动向 FreeSWITCH 发送
BYE强行切断通话!
💡 send_silence_when_idle=-1 的工作原理
-1表示永久持续生效(若设为正整数则代表持续若干毫秒);- 当通道处于空闲状态(当前既无文件 playback,也无流式 TTS 灌包)时,FreeSWITCH 内核时钟会自动按照当前协商的编解码器(如 PCMA/PCMU/G.722/Opus)标准包频(每 20ms 一包),持续向对端生成并发送标准的舒适静音(Comfort Noise)或全零静音载荷;
- 使得整条 UDP RTP 链路在呼叫全生命周期内保持高频双向心跳,100% 根治因静音等待引发的 NAT 断流、防火墙阻断与运营商强制挂机问题。
变量解耦配置说明: 统一使用宏变量
$${esl_host}(在vars.xml中定义,如192.168.2.246:9911或127.0.0.1:9911)。无论callflow-esl跑在本地 WSL、宿主机还是独立应用服务器,仅需在vars.xml修改单点即可全局生效。
3. RTP 媒体流端口范围与防火墙安全组
配置文件路径:freeswitch-install/etc/freeswitch/autoload_configs/switch.conf.xml
xml
<configuration name="switch.conf" description="Core Configuration">
<settings>
<!-- 设置 FreeSWITCH RTP 动态端口范围 -->
<param name="rtp-start-port" value="30000"/>
<param name="rtp-end-port" value="30199"/>
</settings>
</configuration>重要约束:
- 严禁端口冲突:如果同时部署了
coturn服务,coturn的 relay 端口范围(如31000-31040/UDP)绝对不能与 FreeSWITCH 的 RTP 端口范围重叠。- 防火墙放行:云服务器公网安全组必须放行
30000-30199/UDP端口段。
4. WebRTC 与 TLS / WSS 证书配置
- WebRTC 监听端口(位于
sip_profiles/internal.xml):xml<!-- SIP over WS 端口 --> <param name="ws-binding" value=":5066"/> <!-- SIP over Secure WSS 端口 --> <param name="wss-binding" value=":7443"/> - 证书替换:
freeswitch-install/etc/freeswitch/tls/目录中的wss.pem和dtls-srtp.pem为开发测试自签名样例证书。生产环境使用 WebRTC 时,必须替换为正式域名证书:wss.pem:包含服务器证书与私钥的合成 PEM 文件;dtls-srtp.pem:DTLS-SRTP 媒体流加密证书。
5. 通话录音持久化与 Nginx 托管
- 录音持久化路径: 通话录音默认保存于宿主机
freeswitch-install/var/recordings/。 - Nginx 静态托管:
docker-compose.yml中已编排fs-recordings-nginx服务,将该目录只读挂载至 Nginx,监听宿主机8088端口:- 配置文件:
nginx/conf.d/recordings.conf - Web 访问路径:
http://<server-ip>:8088/recordings/<call-uuid>.wav - 支持跨域(
Access-Control-Allow-Origin: *)与Accept-Ranges: bytes音频拖拽播放。
- 配置文件:
- 平台服务联动: 在
apps/callout-server/config.toml或apps/callflow-server/config.toml中,将录音基础 URL 配置为:tomlrecordingBaseUrl = "http://<fs-host>:8088/recordings"
6. 内部分机用户管理 (directory/default/)
- 预置分机文件:
1000.xml~1019.xml(共 20 个测试分机)。 - 注册密码:默认继承
vars.xml中的$${default_password},也可在单个分机 XML 中单独指定<param name="password" value="YourPass"/>。