WebRTC 让浏览器具备了实时通信能力,但企业现网中仍有大量基于 SIP 的 IP 话机、PBX 和运营商 trunk。要让 Web 用户拨打传统分机号,需要在两种协议之间搭建桥梁——这就是 SIP-WebRTC 网关的核心价值。

架构全景

典型的融合架构包含四个组件:

信令和媒体必须解耦设计——信令网关可以无状态扩展,媒体网关则需要关注 CPU 和带宽。

信令桥接要点

浏览器端使用 wss:// 连接信令服务器,SIP 消息格式与传统 SIP 一致,但传输层从 UDP 换成了 WebSocket。网关需要处理:

  1. Contact 头重写:将 WebSocket 端的 Contact 映射为网关可达的 SIP URI
  2. Via 头追加:确保响应能沿正确路径返回
  3. SDP 地址修正:WebRTC 的 ICE candidate 需要与媒体网关地址对齐
  4. 鉴权统一:Digest 认证在 WebSocket 和 UDP 侧保持一致

媒体面:转码还是直通?

WebRTC 强制使用 Opus(音频)和 VP8/VP9/H.264(视频),而传统 SIP 终端可能只支持 G.711(PCMU/PCMA)或 G.729。媒体网关的两种策略:

# FreeSWITCH 中启用 WebRTC 的配置片段
<param name="ws-binding" value=":5066"/>
<param name="wss-binding" value=":7443"/>
<param name="rtp-ip" value="auto"/>
<param name="sip-ip" value="auto"/>
<param name="tls" value="true"/>
<param name="tls-cert-dir" value="/etc/freeswitch/tls"/>

ICE、STUN、TURN 不可省略

浏览器端的 WebRTC 连接必须经过 ICE 连通性检查。部署清单:

  1. 部署 STUN 服务器(可用 coturn),告知客户端公网 IP
  2. 对称 NAT 或企业防火墙场景配置 TURN 中继
  3. 媒体网关开放 UDP 10000–20000 端口范围
  4. HTTPS 页面必须使用 WSS,否则浏览器会阻止 WebSocket 连接

前端集成:JsSIP 示例

JsSIP 是成熟的浏览器 SIP 库,几行代码即可注册并发起呼叫:

const socket = new JsSIP.WebSocketInterface('wss://pbx.example.com:7443');
const ua = new JsSIP.UA({
  sockets: [socket],
  uri: 'sip:1001@pbx.example.com',
  password: 'secret'
});
ua.start();

// 发起呼叫
const session = ua.call('sip:2000@pbx.example.com', {
  mediaConstraints: { audio: true, video: false }
});

生产环境注意事项

小结

SIP-WebRTC 融合的关键在于信令透明桥接 + 媒体编解码对齐 + NAT 穿透。选对开源组件(FreeSWITCH + coturn + JsSIP)可以快速搭建原型,但上生产前务必做跨网络环境的互通测试。