OpenSIPS 通话中 UPDATE 请求导致没有声音问题

文章目录

  • 1. 问题现象
  • 2. 抓包排查
  • 3. 问题分析及解决方案

1. 问题现象

在 SIP 应用的开发中,通话一端听不到声音是比较常见的问题。一般来说,没有声音意味着 RTP 传输存在障碍,追根究底就是网络不通或者端口未开放等原因。但在实践中,真正造成 RTP 传输故障的原因各式各样,以下是笔者遇到的一个案例:

  1. 坐席使用软电话注册到 OpenSIPS,常驻拉起后拨打外部用户,媒体流传输正常
  2. 坐席使用硬话机注册到 OpenSIPS,常驻拉起后拨打外部用户,没有声音

2. 抓包排查

问题的切入点显而易见,硬话机的行为肯定和软电话存在不一致,从而导致问题的发生。通常遇到这种情况 SIP 抓包是不二的法门,以下是笔者使用 sngrep 抓到的 SIP 交互包,对比可以发现一个明显的差异:

使用硬话机时,在 SDP 协商完成 SIP 会话已经建立的情况下,使用 FreeSWITCH 的 bridge 命令接通坐席和用户时 FreeSWITCH 发出了一个 UPDATE 请求给到 OpenSIPS

OpenSIPS 通话中 UPDATE 请求导致没有声音问题_第1张图片

3. 问题分析及解决方案

在进行问题分析前首先要确定以下两点:

  1. SIP 协议中的 UPDATE 请求
    UPDATE 请求用于不改变会话状态的前提下修改会话的参数,可用于 SDP 的重新协商
  2. OpenSIPS 的媒体代理
    笔者的应用架构中 OpenSIPS 不仅仅具有注册代理的功能,在其核心脚本中也会使用 rtpengine 作为媒体代理服务器。OpenSIPS 进行媒体代理的原理并不复杂,关键逻辑只有两个:
    1. 替换 INVITE 请求中 SDP 的 IP 和端口为媒体代理服务器 IP 端口,再将其转发给 SIP 终端;
    2. 当 SIP 终端响应 200 时,替换响应中 SDP 的 IP 端口为媒体代理服务器 IP 端口,再将其转发给 INVITE 请求的发起端

综合以上信息,再来分析 sngrep 抓到的 SIP 交互就可以发现问题所在:

  1. 经过 OpenSIPS 处理后,由 INVITE 请求响应建立起的会话已经形成了 FreeSWITCH <--> rtpenginertpengine <--> 硬话机 之间的 rtp 传输连接,此时 rtp 传输正常
  2. 在 bridge 接通外部用户和使用硬话机的坐席时,FreeeSWITCH 不知道出于什么原因发起了 UPDATE 请求重新进行 SDP 协商。从 SIP 交互报文看,此次协商的结果是 FreeSWITCH 和 硬话机 绕过了 rtpengine 进行 rtp 直连,而二者之间网络并未打通
  3. 检查 OpenSIPS 脚本,发现脚本中对 INVITE 请求进行了媒体代理,但是未对 UPDATE 请求做任何处理

至此问题原因已经清晰,一个简单快速的解决方案是在 OpenSIPS 脚本中对 UPDATE 请求也进行媒体代理的处理,经修改后问题不复现

你可能感兴趣的:(随笔,工具配置,OpenSIPS,服务器,SIP)