FreeSWITCH 是一个功能极其强大、开源的通信平台,它不仅仅是一个电话交换机(PBX),更是一个构建各种实时通信应用的“瑞士军刀”,这份研究将从多个维度展开,从基础概念到高级应用,希望能为你提供一个全面而深入的指南。

第一部分:FreeSWITCH 是什么?
1 核心定义
FreeSWITCH 是一个用 C 语言编写的、跨平台的、开源的通信软件,它实现了会话发起协议(SIP),并支持多种其他信令协议(如 H.323, WebRTC, Google Talk 等),其核心功能是作为软交换机,负责建立、管理和终止多媒体会话(如语音通话、视频通话、即时消息等)。
2 核心特点
- 开源免费:基于 Apache 2.0 许可证,可以免费使用、修改和分发,商业成本极低。
- 跨平台:支持 Windows, Linux, macOS, BSD 等多种操作系统。
- 高性能和高并发:采用事件驱动的架构,设计上就是为了处理海量并发呼叫,可轻松支持数万甚至数十万并发通话。
- 模块化设计:核心功能非常精简,绝大部分功能(如数据库驱动、编解码器、应用逻辑)都以模块的形式存在,可以按需加载,非常灵活。
- 强大的脚本能力:内置 Event Socket (ESL) 和 Mod_lua 等接口,允许使用 Lua, Python, Perl, JavaScript 等多种语言进行二次开发和控制,实现复杂的业务逻辑。
- 丰富的应用生态:可以与 Asterisk (通过 PSTN Gateway 或 Gateway 模块)、Kamailio 等其他开源通信项目集成,也可以连接各种 SIP/IAX 中继和终端设备。
- 强大的多媒体支持:原生支持 WebRTC,可以轻松构建网页电话、移动 App 通话等功能,支持 G.711, G.729, Opus, H.264, H.265 等各种音视频编解码。
第二部分:核心架构与工作原理
理解 FreeSWITCH 的架构是掌握它的关键。
1 核心组件
freeswitch进程:主程序,是整个系统的大脑,它负责解析配置、加载模块、监听端口、分发事件。- 配置文件:位于
/usr/local/freeswitch/conf/目录下。sip_profiles/: 定义 SIP 监听地址、端口、传输方式(UDP/TCP/TLS)等。dialplan/: 呼叫路由逻辑,决定一个来电该如何处理。directory/: 用户和分机的认证信息(用户名、密码等)。autoload_configs/: 模块的配置文件。
- 模块:FreeSWITCH 的功能扩展。
mod_sofia: 核心模块,处理 SIP 协议。mod_event_socket: 提供 ESL 接口,供外部程序控制。mod_lua: 支持 Lua 脚本。mod_verto: 支持 WebRTC 客户端。
- Event Socket (ESL):这是 FreeSWITCH 的“灵魂”之一,它是一个 TCP 服务器,外部应用可以通过它发送命令给 FreeSWITCH(如
originate发起呼叫),也可以订阅 FreeSWITCH 的事件(如CHANNEL_CREATE,CHANNEL_ANSWER,CHANNEL_HANGUP),这使得 FreeSWITCH 可以被完美地集成到任何业务系统中。 - 拨号计划:FreeSWITCH 的“路由表”,当有呼叫进入时,FreeSWITCH 会按照拨号计划中定义的规则(从上到下,从左到右)进行匹配,并执行对应的动作,拨号计划支持 XML 和 两种格式,XML 更常用。
2 基本呼叫流程
一个典型的 SIP 呼叫流程如下:
- 呼叫发起:用户 A 通过 SIP 电话或 App 发起一个呼叫请求(
INVITE)到 FreeSWITCH。 - 认证与路由:FreeSWITCH 的
sofia模块收到请求,检查directory中的用户认证信息,认证通过后,dialplan模块开始匹配被叫号码(用户 B 的分机号1001)。 - 执行动作:拨号计划匹配成功,执行预设的动作,
bridge(桥接)。bridge动作会告诉 FreeSWITCH 将这个呼叫路由到目标 URI(如user/1001@${domain})。 - 呼叫建立:FreeSWITCH 向用户 B 发送
INVITE请求,用户 B 的电话振铃,向 FreeSWITCH 返回180 Ringing。 - 应答:用户 B 摘机,向 FreeSWITCH 发送
200 OK,FreeSWITCH 再将此状态转发给用户 A,RTP 流在用户 A 和用户 B 之间建立,通话开始。 - 呼叫结束:任何一方挂机,会发送
BYE请求,FreeSWITCH 清理会话资源,并向另一方发送挂机通知,最后触发CHANNEL_HANGUP事件。
第三部分:关键技术点
1 拨号计划
拨号计划是控制呼叫流程的核心,一个典型的 XML 拨号计划条目如下:

<!-- conf/dialplan/default.xml -->
<context name="default">
<extension name="Local_Extension" continue="false" uuid="...">
<condition field="destination_number" expression="^(\d{4})$">
<!-- 匹配 4 位分机号 -->
<action application="export" data="dialed_extension=$1" />
<action application="answer" />
<action application="sleep" data="1000"/>
<action application="bridge" data="user/${dialed_extension}@${domain}" />
<!-- 如果桥接失败,播放忙音 -->
<action application="playback" data="silence://20" />
<action application="playback" data="phrase:please_try_again_later" />
</condition>
</extension>
</context>
<extension>: 定义一个呼叫路由规则。<condition>: 匹配条件,如destination_number(被叫号码)、caller_id_number(主叫号码) 等。<action>: 执行的动作,如bridge(桥接)、answer(应答)、playback(播放音频)、hangup(挂机) 等。
2 Event Socket (ESL)
ESL 是连接 FreeSWITCH 与外部世界的桥梁,一个典型的 Python 使用 pyesl 库的例子:
import ESL
# 连接到 FreeSWITCH
con = ESLconnection('127.0.0.1', '8021', 'ClueCon')
# 发送命令发起一个呼叫
uuid = con.api('originate', 'sofia/external/13800138000@mygateway.com 1001 default').getBody()
# 订阅所有事件
con.sendevent('PLAIN', 'Event-Name: CUSTOM\nEvent-Subclass: MYAPP\n')
通过 ESL,你可以构建一个呼叫中心系统,当有电话呼入时,你的业务系统可以通过 ESL 获取来电信息,查询客户数据库,然后将呼叫转接到最合适的坐席。
3 WebRTC 集成
FreeSWITCH 对 WebRTC 的支持非常完善,主要通过 mod_verto 模块实现。
- 配置:在
verto.conf.xml中定义 WebRTC 客户端的认证信息。 - 前端:使用
Jssip.js或PJSIP.js等 JavaScript 库构建一个网页。 - 信令交互:网页通过 WebSocket 连接到 FreeSWITCH 的
wss://端口,进行 SIP 信令交互(注册、呼叫、挂机等)。 - 媒体交互:一旦呼叫建立,网页和 FreeSWITCH 之间会直接建立 P2P 的 WebRTC 连流,进行音视频通话。
这使得你可以轻松开发出无需安装任何插件的网页电话。

第四部分:应用场景
基于 FreeSWITCH 强大的能力,可以构建各种复杂的通信应用:
- 企业级 PBX/IPPBX:替代昂贵的商业电话系统,为企业提供内部通话、外部呼入呼出、语音留言、会议等功能。
- 呼叫中心系统:
- ACD (自动呼叫分配):根据技能、队列等规则将呼叫分配给坐席。
- IVR (交互式语音应答):通过语音菜单引导用户,完成信息查询、业务办理等。
- CTI (计算机电话集成):将电话系统与 CRM
