一、为什么通话建立后还会继续看到 SIP 消息
很多初学者会下意识认为:INVITE 成功、ACK 发完之后,SIP 的工作就结束了,后面只剩媒体流。实际上并不是这样。一个已经建立的会话,在持续期间仍可能发生很多控制行为,例如:
- 改变编解码能力
- 调整媒体地址或端口
- 保持会话存活
- 执行保持(hold)与恢复(resume)
- 协商新的媒体流
这些都可能通过会话中的修改类请求来完成。
二、re-INVITE 的作用
re-INVITE 可以理解为:在同一个对话内,再发起一次对会话参数的重新协商。它常见于以下场景:
- 改变 SDP 中的媒体地址
- 发起保持或取消保持
- 调整编解码列表
- 更新某些会话相关参数
它之所以重要,是因为很多媒体变化都不是“悄悄发生”的,而需要双方通过新的 Offer/Answer 再次达成一致。
三、UPDATE 和 re-INVITE 的区别
UPDATE 也是用于修改会话参数的请求,但它通常不改变对话本身,而更偏向在对话早期或已建立后快速更新会话描述。
从理论上理解,两者的差别可以这样抓:
- re-INVITE:更像“重新发起一次对当前会话参数的正式修改流程”
- UPDATE:更像“在不改变邀请语义的前提下更新会话状态”
它们都可能承载新的 Offer/Answer,但适用时机与事务语义并不完全相同。
四、保持(Hold)与恢复(Resume)为什么本质上也是会话修改
在很多实现中,保持并不意味着媒体彻底停止,而是通过 SDP 里的方向属性变化来表达,例如 sendonly、inactive 等。因此 hold / resume 的核心仍然是媒体协商变化,而不是单纯“按下了一个静音按钮”。
五、Session Timer 是什么
Session Timer 用于控制一个已建立会话是否应被周期性刷新。它解决的问题是:如果网络异常或一方失联,系统不能无限期认为会话仍然有效。
它通常会引入一些额外概念:
- 会话刷新间隔
- 谁负责发起刷新请求
- 如果刷新失败,会话应如何超时回收
六、为什么 Session Timer 不等于传输层 keepalive
这两者常被混淆,但关注层次不同:
- keepalive 更偏向连接/NAT 映射维持
- Session Timer 更偏向业务层的会话存续判断
所以即使底层连接还活着,业务层也可能因为 Session Timer 没有被刷新而判定会话失效。
七、会话中修改为什么容易和早期协商、ACK、PRACK 搞混
原因在于它们都可能涉及 SDP,但发生阶段不同:
- 初始 INVITE 阶段:建立会话
- 1xx / PRACK 阶段:处理早期协商和可靠临时响应
- 对话建立后:通过 re-INVITE / UPDATE 做后续修改
要避免混淆,关键是先判断当前请求处于哪个事务与对话阶段。
八、抓包时怎么看这类请求
- 确认当前是否已处于已建立对话中
- 看消息是否携带新的 SDP
- 判断这是为了保持、恢复、刷新还是能力变更
- 结合响应确认新一轮 Offer/Answer 是否完成
九、总结
会话中修改类请求说明了一件很重要的事:SIP 会话不是“建立之后就静止不动”,而是一个可以持续被调整、刷新和重新协商的过程。
- re-INVITE 强调对话内的正式会话参数修改
- UPDATE 强调更灵活的会话更新
- Session Timer 强调业务层会话的生存期管理
理解这组机制后,再看保持、恢复、媒体变更、通话中参数调整等现象,就会更容易建立整体认知。