在VoNR/VoLTE的IMS网络中,SIP会话建立在INVITE/200 OK握手之后,但无线链路随时可能中断——UE掉电、切换失败、覆盖空洞——而对端和网络侧可能毫不知情。如果没有主动保活机制,核心网将一直为这些"幽灵会话"占用RTP承载资源和IMS会话状态。
SIP Session Timer机制(RFC 4028,3GPP TS 24.229 Section 7.7引用)通过周期性发送re-INVITE或UPDATE来刷新会话状态。任何网元(UE、P-CSCF、S-CSCF、AS)在刷新超时后,有权单方面终止会话并释放资源。这个机制看似简单,实际上在IMS多跳架构中,Min-SE与Session-Expires的协商博弈和refresher角色竞争是网络工程师最常遇到的信令问题之一。
| Header字段 | 方向 | 含义 | 典型取值 |
|---|---|---|---|
Session-Expires (或简写x) |
INVITE/UPDATE请求及2xx响应 | 提议/确认的会话刷新间隔(秒) | 600-1800 |
Min-SE |
INVITE请求/422响应/任意proxy插入 | 本端可接受的最小刷新间隔(秒) | 90-1800 |
refresher (Session-Expires子参数) |
2xx响应中 | 指定由哪一方负责发起刷新:uac或uas |
- |
Supported: timer |
请求/响应 | 声明本端支持Session Timer扩展 | - |
Require: timer |
请求 | 强制要求对端支持Session Timer | - |
graph TD
A[UAC提议 Session-Expires: 600<br/>Min-SE: 90] --> B{沿途Proxy检查}
B -->|Session-Expires >= Proxy Min-SE| C[Proxy放行<br/>可上调Min-SE]
B -->|Session-Expires < Proxy Min-SE| D[Proxy拒绝 422<br/>携带自己的Min-SE]
C --> E{UAS检查}
E -->|Session-Expires >= UAS Min-SE| F[UAS接受<br/>2xx携带协商后的Session-Expires<br/>指定refresher角色]
E -->|Session-Expires < UAS Min-SE| G[UAS拒绝 422<br/>携带自己的Min-SE]
D --> H[UAC用422中的Min-SE重发INVITE]
G --> H
F --> I[会话建立<br/>refresher方周期性re-INVITE/UPDATE]
sequenceDiagram
participant UE1 as 主叫UE (UAC)
participant PCSCF1 as P-CSCF (主叫侧)
participant SCSCF1 as S-CSCF (主叫侧)
participant SCSCF2 as S-CSCF (被叫侧)
participant PCSCF2 as P-CSCF (被叫侧)
participant UE2 as 被叫UE (UAS)
Note over UE1,UE2: 阶段1: INVITE协商 — 首次尝试被422拒绝
UE1->>PCSCF1: INVITE (SDP offer)<br/>Session-Expires: 600;refresher=uac<br/>Min-SE: 90<br/>Supported: timer
Note right of PCSCF1: P-CSCF策略要求<br/>Min-SE >= 1800
PCSCF1-->>UE1: 422 Session Interval Too Brief<br/>Min-SE: 1800
Note left of UE1: UAC收到422后<br/>必须使用422中的Min-SE<br/>重新发起INVITE
Note over UE1,UE2: 阶段2: 重发INVITE — 协商成功
UE1->>PCSCF1: INVITE (SDP offer)<br/>Session-Expires: 1800<br/>Min-SE: 1800<br/>Supported: timer
PCSCF1->>SCSCF1: INVITE (转发)<br/>Session-Expires: 1800<br/>Min-SE: 1800
SCSCF1->>SCSCF2: INVITE (转发)
SCSCF2->>PCSCF2: INVITE (转发)
PCSCF2->>UE2: INVITE (转发)
UE2->>PCSCF2: 180 Ringing
PCSCF2->>SCSCF2: 180 Ringing
SCSCF2->>SCSCF1: 180 Ringing
SCSCF1->>PCSCF1: 180 Ringing
PCSCF1->>UE1: 180 Ringing
UE2->>PCSCF2: 200 OK (SDP answer)<br/>Session-Expires: 1800;refresher=uac
PCSCF2->>SCSCF2: 200 OK (转发)
SCSCF2->>SCSCF1: 200 OK (转发)
SCSCF1->>PCSCF1: 200 OK (转发)
PCSCF1->>UE1: 200 OK (转发)
UE1->>PCSCF1: ACK
PCSCF1->>SCSCF1: ACK → ... → UE2
Note over UE1,UE2: 会话建立完成<br/>Session-Expires = 1800秒<br/>Refresher = UAC (主叫UE)
Note over UE1,UE2: 阶段3: 周期性刷新 (1800秒后)
UE1->>PCSCF1: re-INVITE (无SDP 或 带SDP)<br/>Session-Expires: 1800;refresher=uac
PCSCF1->>SCSCF1: re-INVITE (转发)
SCSCF1->>SCSCF2: re-INVITE (转发)
SCSCF2->>PCSCF2: re-INVITE (转发)
PCSCF2->>UE2: re-INVITE (转发)
UE2->>PCSCF2: 200 OK<br/>Session-Expires: 1800;refresher=uac
PCSCF2->>SCSCF2: 200 OK → ... → UE1
UE1->>PCSCF1: ACK → ... → UE2
Note over UE1,UE2: 刷新成功,定时器重置
Note over UE1,UE2: 阶段4: 刷新失败场景
UE1-xPCSCF1: re-INVITE (超时无响应)
Note left of UE1: 定时器到期<br/>UE1发送BYE终止会话
UE1->>PCSCF1: BYE
PCSCF1->>SCSCF1: BYE → ... → UE2
Note over UE1,UE2: 会话终止,资源释放
INVITE中的Session Timer相关Header:
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]:5060;branch=z9hG4bK1234
Max-Forwards: 70
Route: <sip:pcscf.mnc.mcc.3gppnetwork.org:5060;lr>
Route: <sip:scscf.mnc.mcc.3gppnetwork.org:5060;lr>
Supported: timer, 100rel, precondition, update
Session-Expires: 1800;refresher=uac
Min-SE: 1800
Content-Type: application/sdp
422拒绝响应:
SIP/2.0 422 Session Interval Too Brief
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]:5060;branch=z9hG4bK1234
From: <sip:[email protected]>;tag=abc123
To: <sip:[email protected]>;tag=def456
Min-SE: 1800
200 OK中的确认:
SIP/2.0 200 OK
Via: SIP/2.0/UDP ...
Session-Expires: 1800;refresher=uac
RFC 4028 Section 7.4定义了422的处理规则,但在IMS多跳架构中,每一个proxy都可以独立设置自己的Min-SE。考虑以下场景:
UE: Min-SE = 90
P-CSCF: Min-SE = 1800
S-CSCF: Min-SE = 2400
AS (TAS/MRFC): Min-SE = 3600
| 跳数 | 触发422的网元 | 422中的Min-SE | UAC重发值 |
|---|---|---|---|
| 第1次 | P-CSCF | 1800 | Session-Expires: 1800 |
| 第2次 | S-CSCF | 2400 | Session-Expires: 2400 |
| 第3次 | AS | 3600 | Session-Expires: 3600 |
RFC 4028规定:UAC在收到422后,必须将Session-Expires设为不小于422响应中Min-SE的值。但规范并未限制沿途Proxy的Min-SE递增上限——这意味着如果各网元配置不一致,理论上可能出现多次422往返。
3GPP TS 24.229 Section 5.7.2.1对此做了IMS层面的约束:P-CSCF作为接入侧的第一个信令锚点,应负责统一Min-SE策略,在信令向S-CSCF转发前就完成Min-SE的统一调整。
RFC 4028 Section 7.3定义了三种Proxy行为:
| 行为 | 条件 | 操作 |
|---|---|---|
| 插入Min-SE | INVITE中无Min-SE,且Proxy有本地策略 | 添加Min-SE header |
| 增大Min-SE | INVITE中Min-SE < Proxy本地策略 | 将Min-SE提升至本地策略值 |
| 拒绝并返回422 | INVITE中Session-Expires < Proxy本地Min-SE | 返回422,携带Proxy的Min-SE |
设计意图:Proxy作为中间网元,不能擅自缩短Session-Expires(这是端到端协商的结果),但可以通过Min-SE机制提高下限。这保证了网络运营商对流量的管控权——运营商可以通过配置P-CSCF的Min-SE来强制UE以合理的间隔刷新会话。
Session-Expires的refresher参数决定了谁负责发起周期性刷新。确定规则如下:
flowchart TD
A[INVITE携带 Session-Expires<br/>refresher参数?] -->|有, refresher=uac| B[UAS在2xx中确认 refresher=uac<br/>UAC负责刷新]
A -->|有, refresher=uas| C[UAS在2xx中确认 refresher=uas<br/>UAS负责刷新]
A -->|无refresher参数| D{UAS在2xx中指定<br/>refresher}
D -->|UAS选择 uac| E[UAC负责刷新]
D -->|UAS选择 uas| F[UAS负责刷新]
A -->|无Session-Expires| G{UAS是否支持timer?}
G -->|是, UAS主动添加| H[UAS在2xx中添加<br/>Session-Expires;refresher=uas]
G -->|否| I[无Session Timer<br/>会话无保活]
当INVITE和2xx都没有指定refresher时(即双方都声称支持timer但都不指定角色),RFC 4028 Section 7.2规定:
如果2xx响应中没有refresher参数,UAC默认为refresher。
这是为了避免双方都不刷新导致的会话泄漏。但在IMS实际部署中,更常见的做法是:P-CSCF或S-CSCF作为B2BUA,会主动在信令中插入或修改refresher参数,确保刷新责任明确。
| 特性 | re-INVITE刷新 | UPDATE刷新 |
|---|---|---|
| SDP协商 | 可以携带SDP(刷新+修改编解码) | 必须携带SDP(RFC 3311) |
| 对目标URL的影响 | Target-Refresh请求,更新Contact | 非Target-Refresh,不更新路由 |
| 可靠性 | 需要可靠响应+ACK | 简单请求/响应 |
| IMS推荐 | TS 24.229默认推荐re-INVITE | 适用于SDP参数微调 |
| 误判风险 | re-INVITE用于刷新和修改混合,解析困难 | 目的明确 |
3GPP TS 24.229 Section 5.1.3A规定:UE应使用re-INVITE进行会话刷新,但也可以使用UPDATE。P-CSCF必须同时支持两种刷新方式。
stateDiagram-v2
[*] --> Idle: UE开机/无会话
Idle --> Negotiating: 发送/接收INVITE<br/>携带Session-Expires
Negotiating --> Rejected422: 收到422<br/>Session Interval Too Brief
Rejected422 --> Negotiating: 重发INVITE<br/>使用422中的Min-SE
Negotiating --> Established: 收到/发送2xx<br/>Session-Expires协商完成
Established --> RefreshPending: Session Timer触发<br/>(到达过期前阈值)
RefreshPending --> Refreshing: Refresher方发送<br/>re-INVITE/UPDATE
Refreshing --> Established: 收到2xx<br/>定时器重置
Refreshing --> RefreshFailed: 超时无响应<br/>或收到错误响应
RefreshFailed --> Terminating: 定时器彻底到期<br/>发送BYE终止
Established --> Terminating: 正常挂机<br/>发送/接收BYE
Terminating --> Idle: 会话资源释放
note right of Negotiating
关键IE: Session-Expires
Min-SE, Supported: timer
end note
note right of RefreshPending
触发时机 = Session-Expires - δ
δ通常为64*T1 (RFC 3261)
end note
| 网元 | TS 24.229章节 | 核心行为 | 可配置项 |
|---|---|---|---|
| UE | 5.1.3A | 支持timer扩展,支持re-INVITE/UPDATE刷新 | Session-Expires默认值、Min-SE |
| P-CSCF | 5.7.2.1 | 作为接入锚点,执行Min-SE策略强制;Gq接口通知PCRF承载资源状态 | 本地Min-SE策略、是否强制timer |
| S-CSCF | 5.7.1.2 | 转发Session Timer参数;可按用户订阅级别覆盖Min-SE | 按iFC触发的AS列表Min-SE |
| AS/TAS | 5.7.3 | B2BUA模式下可独立管理两腿的Session Timer;SIP AS模式下透明转发 | 业务逻辑相关Min-SE |
| BGCF | 5.7.4 | 透明转发Session Timer参数 | 通常不修改 |
| MGCF | 5.7.5 | ISUP/BICC与SIP的Session Timer互操作;ISUP无对应机制时MGCF自行管理 | CS域超时映射 |
P-CSCF在Session Timer机制中承担了最关键的策略执行角色:
这是3GPP在TS 24.229 Section 5.7.2.1中的强制要求,确保IMS网络中不会出现P-CSCF不知道会话已经泄漏的情况。
# 过滤422响应
sip.Status-Code == 422
# 过滤携带Session-Expires的INVITE
sip.Method == "INVITE" && sip.Header.Session-Expires exists
# 过滤re-INVITE(可能是刷新)
sip.Method == "INVITE" && sip.Header.Session-Expires exists && !sip.CSeq.method == "INVITE"
# 更精确:通过CSeq识别re-INVITE(CSeq > 1)
# 过滤Min-SE header
sip.Header.Min-SE exists
| 故障现象 | 根因分析 | 排查步骤 |
|---|---|---|
| 反复422循环 | P-CSCF和S-CSCF的Min-SE配置不一致,S-CSCF的Min-SE大于P-CSCF | 检查各网元Min-SE配置,确保P-CSCF >= S-CSCF >= AS |
| 会话建立后一段时间被BYE终止 | refresher方未按时发送re-INVITE/UPDATE | 检查UE的定时器实现;确认re-INVITE是否被中间网元拦截 |
| re-INVITE触发编解码重新协商导致音频中断 | 刷新re-INVITE携带了新的SDP offer | UE应在不修改媒体参数时发送无SDP的re-INVITE或固定SDP |
| 被叫方也发送刷新导致冲突 | 双方都认为自己是refresher | 检查2xx中refresher参数是否正确 |
| P-CSCF发送BYE但UE不响应 | P-CSCF本地定时器超时,但UE认为会话仍有效 | 确认P-CSCF与UE的Session-Expires值是否一致 |
| ## 九、与其他保活机制的对比 |
| 机制 | 协议层 | 检测粒度 | 刷新方式 | IMS适用性 |
|---|---|---|---|---|
| SIP Session Timer (RFC 4028) | SIP应用层 | 端到端+逐跳 | re-INVITE/UPDATE | VoNR/VoLTE标准机制 |
| RTP/RTCP超时检测 | 媒体传输层 | 端到端 | 被动检测 | 辅助手段,无法主动释放 |
| OPTIONS Ping | SIP应用层 | 逐跳 | OPTIONS请求 | 网元间心跳,非会话级 |
| SIP NOTIFY保活 | SIP应用层 | 订阅级 | NOTIFY | 仅限subscription场景 |
| QoS监控 (PCF/PCRF) | 策略控制层 | 承载级 | Gq/A Rx事件报告 | 与P-CSCF联动 |
SIP Session Timer的核心优势在于:它是在SIP信令层面实现的端到端保活,可以穿透NAT和防火墙,同时允许沿途每个proxy独立检测会话活性。这是RTCP超时检测等媒体层方案无法替代的。
3GPP TS 24.229在Rel-18中针对Session Timer的主要更新包括:
Q1: Session Timer的刷新阈值如何计算?
A: RFC 4028规定,refresher方应在Session-Expires到期前发送刷新请求。具体触发时间为:Session-Expires - δ,其中δ = 64 × T1(T1是SIP事务定时器,默认500ms,所以δ ≈ 32秒)。也就是说,如果Session-Expires=1800秒,UE会在约1768秒时发起re-INVITE刷新。
Q2: 422响应可以触发多少次重试? A: RFC 4028没有定义最大重试次数,理论上只要沿途还有更大Min-SE的网元,就会持续触发422。但IMS最佳实践要求:P-CSCF应配置为全网最大的Min-SE值,确保在接入侧就完成最终协商,避免422穿透到S-CSCF或AS。
Q3: re-INVITE刷新时是否必须携带SDP? A: 不是。RFC 4028明确说明:刷新用的re-INVITE可以不携带SDP body(即"session refresh re-INVITE without SDP")。这种情况下,对端在200 OK中也不携带SDP,双方媒体参数不变。这是推荐做法——避免刷新请求意外触发编解码重新协商。
Q4: P-CSCF在Session Timer超时后能否不发送BYE直接释放资源? A: TS 24.229 Section 5.7.2.1要求P-CSCF在定时器超时后必须发送BYE通知对端,同时通过Rx/N5接口通知PCF释放承载资源。直接静默释放会导致对端网元的会话状态残留。
Q5: VoNR和VoLTE在Session Timer机制上有何差异? A: 从SIP信令层面完全一致,差异在底层:VoNR的P-CSCF通过N5接口(5G)通知PCF,而VoLTE的P-CSCF通过Rx接口(4G)通知PCRF。P-CSCF检测到超时后通知的策略控制网元不同,但SIP层面的Session Timer行为完全相同。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
