问题描述
- fs主动发起外呼
- 外呼接通,通话正常建立
- 一分钟后,fs主动发起invite请求
- 对端不认可reinvite请求,直接回复503
- 本地fs收到对端回复503,直接挂断通话
问题分析
sip中有session-timer的机制,用于确保对话过程中,对端仍然在线。
因为都是udp链接的,对端即使掉线了,我们本地也无法感知,只能通过再次invite来进行试探。(该invite请求和第一个发送的请求基本一致)
一般情况下,发送reinvite的间隔是1分钟。
在当前这个问题中,对端不认可我们发送的reinvite,本地的fs理所应当的认为通话已经无效,所以直接拆线。
介绍: SIP(RFC3261)没有提供已存在会话保持激活的机制,虽然可以终端可以使用某些方式了解会话是否存活,但proxy却无法做到这一点。Re-INVITE和UPDATE方法就基于此进行的,这些刷新请求的周期是通过协商来确定的。当在规定的周期内没有新的刷新请求到来,即认为该会话结束。
运作:
1)首先,UAC在INVITE方法中的Supported头域中加入timer标签,表示支持该RFC;
2)当请求通过proxies时,它们在请求中加入或修改已存在的Session-Expires和Min-SE头域;(其中Min-SE头域中的值只能增加不能减少,Session-Expires头域的值只能减少不能增加,但不能少于Min-SE头域中的值);
3)当Proxy无法接受请求中的Session-Expires值时(小于Min-SE值),Proxy会回复422,UAC会继续发起请求,但会携带422中的Min-SE头域;
4)当请求到达UAS时,UAS会在2**的应答中Session-Expires头域中填写最后的结果,且会携带参数refresher(指示当前的UAC或UAS谁来进行刷新)。2**的回复,Proxy无法修改Session-Expires头域。
5)此后在协商的Session-Expires时间内,UA会发起新的刷新请求,如果刷新失败(发起者收不到回应或收到408、481,接受者收不到请求),则发送BYE消息。
当通话一旦开始即发送刷新请求。一般来说,如果支持该RFC的话,最后刷新一般使用UPDATE方法。
引用自:链接
问题解决
有两个解决问题的方向:
- 对端认可我们发送的reinvite请求,这个难度较大
- 我们本地关闭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关闭掉