问题描述

  1. fs主动发起外呼
  2. 外呼接通,通话正常建立
  3. 一分钟后,fs主动发起invite请求
  4. 对端不认可reinvite请求,直接回复503
  5. 本地fs收到对端回复503,直接挂断通话

问题分析

sip中有session-timer的机制,用于确保对话过程中,对端仍然在线。
因为都是udp链接的,对端即使掉线了,我们本地也无法感知,只能通过再次invite来进行试探。(该invite请求和第一个发送的请求基本一致)
一般情况下,发送reinvite的间隔是1分钟。
在当前这个问题中,对端不认可我们发送的reinvite,本地的fs理所应当的认为通话已经无效,所以直接拆线。

介绍: SIP(RFC3261)没有提供已存在会话保持激活的机制,虽然可以终端可以使用某些方式了解会话是否存活,但proxy却无法做到这一点。Re-INVITE和UPDATE方法就基于此进行的,这些刷新请求的周期是通过协商来确定的。当在规定的周期内没有新的刷新请求到来,即认为该会话结束。

运作:

  1. 1)首先,UACINVITE方法中的Supported头域中加入timer标签,表示支持该RFC
  2. 2)当请求通过proxies时,它们在请求中加入或修改已存在的Session-ExpiresMin-SE头域;(其中Min-SE头域中的值只能增加不能减少,Session-Expires头域的值只能减少不能增加,但不能少于Min-SE头域中的值);
  3. 3)当Proxy无法接受请求中的Session-Expires值时(小于Min-SE值),Proxy会回复422UAC会继续发起请求,但会携带422中的Min-SE头域;
  4. 4)当请求到达UAS时,UAS会在2**的应答中Session-Expires头域中填写最后的结果,且会携带参数refresher(指示当前的UACUAS谁来进行刷新)。2**的回复,Proxy无法修改Session-Expires头域。
  5. 5)此后在协商的Session-Expires时间内,UA会发起新的刷新请求,如果刷新失败(发起者收不到回应或收到408481,接受者收不到请求),则发送BYE消息。
  6. 当通话一旦开始即发送刷新请求。一般来说,如果支持该RFC的话,最后刷新一般使用UPDATE方法。

引用自:链接

问题解决

有两个解决问题的方向:

  1. 对端认可我们发送的reinvite请求,这个难度较大
  2. 我们本地关闭session-timer机制,对端是运营商,默认人家就不掉线吧。

针对第二个解决方案,方法如下:
文件:conf/sip_profiles/external.xml
将里面的enable-timer设置为false

参考文档

SIP Session Timers 参考RFC4028:很棒的参考文档
https://tools.ietf.org/html/rfc4028
https://groups.google.com/g/sip_js/c/rLXRMNy3KfY:提示sofia.conf.xml里面将enable-timer关闭掉