在IMS注册流程被反复讨论之后,有一个看似不起眼、却支撑整个IMS"网络可感知终端在线状态"能力的机制长期被忽略——注册事件包(reg event package)的SUBSCRIBE/NOTIFY订阅。当UE成功注册到S-CSCF后,P-CSCF并不是就此"撒手不管",它会立即向S-CSCF发起一次针对该用户公共身份(IMPU)的reg事件订阅;之后只要该用户的注册状态发生任何变化(重注册、去注册、网络侧强制去注册),S-CSCF都会通过NOTIFY把状态推送给P-CSCF(以及订阅了该事件的应用服务器AS)。本文基于 3GPP TS 24.229、TS 23.228 以及 RFC 3680,对该机制的信令时序、关键IE、reginfo状态机与XML结构进行全链拆解。
REGISTER方法是SIP用来建立"AoR↔Contact绑定"的手段,但REGISTER本身是拉取式(pull)的:它只能由UE主动发起。网络侧(S-CSCF)无法用REGISTER去"通知"UE或P-CSCF"你的注册已经被撤销了"。这就带来了三个实际问题:
reg事件包就是为了解决"注册状态变化的异步推送"而设计的事件通知通道。它把注册状态建模为一个有限状态机,订阅者订阅后,状态机的每次迁移都会触发一个携带application/reginfo+xml正文的NOTIFY。
flowchart TD
A[REGISTER 拉取式<br/>UE主动发起] -->|建立绑定| B[AoR↔Contact<br/>S-CSCF维护状态机]
B -->|状态变化| C{事件触发}
C -->|订阅存在| D[SUBSCRIBE/NOTIFY 推送式<br/>网络侧异步通知]
D --> E1[P-CSCF: 释放IP-CAN/PCF会话]
D --> E2[AS: 欢迎短信/Presence/iFC业务]
D --> E3[UE: 强制重新鉴权]
C -->|无订阅| F[静默变更<br/>资源泄漏风险]
style D fill:#e8f5e9,stroke:#2e7d32
style F fill:#ffebee,stroke:#c62828
在IMS中,S-CSCF始终是reg事件的notifier(通知者),因为它持有注册状态库;订阅者(subscriber)主要有两类:P-CSCF(在初始注册成功后立即订阅)和AS(由第三方REGISTER触发后订阅)。两者并行存在,互不影响。
P-CSCF在收到对初始REGISTER的200 OK后(此时它已从Service-Route头域获知S-CSCF的地址),立即生成SUBSCRIBE:
sequenceDiagram
autonumber
participant UE
participant PCSCF as P-CSCF
participant ICSCF as I-CSCF
participant SCSCF as S-CSCF
participant HSS
Note over UE,SCSCF: 阶段一:初始注册(已完成,省略鉴权挑战)
UE->>PCSCF: REGISTER (IMPU, IMPI, Contact)
PCSCF->>ICSCF: REGISTER
ICSCF->>HSS: Cx-UI/UAR (查询S-CSCF能力)
ICSCF->>SCSCF: REGISTER
SCSCF->>HSS: Cx-SAR/SAA (注册/下载用户档案)
SCSCF-->>UE: 200 OK (含 Service-Route → S-CSCF)
Note over PCSCF,SCSCF: 阶段二:P-CSCF发起reg事件订阅
PCSCF->>ICSCF: SUBSCRIBE<br/>Event: reg; Expires: 600000<br/>Request-URI: IMPU(AoR)
ICSCF->>SCSCF: SUBSCRIBE (转发)
SCSCF->>SCSCF: 鉴权订阅者(P-CSCF)<br/>建立订阅dialog
SCSCF-->>PCSCF: 200 OK (SUBSCRIBE)<br/>Dialog建立
Note over PCSCF,SCSCF: 阶段三:立即NOTIFY(全量状态)
SCSCF-->>PCSCF: NOTIFY (full state)<br/>Content-Type: application/reginfo+xml<br/>reginfo state=full
PCSCF-->>SCSCF: 200 OK (NOTIFY)
Note over PCSCF,SCSCF: 阶段四:后续状态变更(如网络去注册)
Note right of SCSCF: HSS Purge / OAM去注册<br/>联系人状态机迁移→terminated
SCSCF-->>PCSCF: NOTIFY (partial)<br/>contact state=terminated, event=deactivated
PCSCF->>PCSCF: 释放IP-CAN/PCF会话
PCSCF-->>SCSCF: 200 OK (NOTIFY)
时序中有几个关键设计点:
iFC机制会在UE注册成功后触发S-CSCF向AS发送第三方REGISTER(第三方是指AS作为"被通知方")。AS收到后,可主动向S-CSCF订阅reg事件,从而在自己的业务逻辑里感知注册变化:
sequenceDiagram
autonumber
participant SCSCF as S-CSCF
participant AS
Note over SCSCF: iFC匹配成功(InitialFilterCriteria)
SCSCF->>AS: 第三方REGISTER<br/>Request-URI: AS URI, To: IMPU
AS-->>SCSCF: 200 OK
Note over AS,SCSCF: AS发起reg订阅(可选,取决于业务)
AS->>SCSCF: SUBSCRIBE Event: reg; Expires
SCSCF-->>AS: 200 OK
SCSCF-->>AS: NOTIFY (full reginfo)
AS-->>SCSCF: 200 OK
Note over AS,SCSCF: 用户注册状态变化→AS感知→执行业务
SCSCF-->>AS: NOTIFY (partial)
Note right of AS: 例: Presence服务器更新presence文档<br/>欢迎短信AS下发SMS
AS-->>SCSCF: 200 OK
AS订阅是"欢迎短信""Presence合成""号码携带后置通知"等业务的技术底座。需要注意的是,并非所有AS都需要订阅——只有需要持续感知注册状态的业务才订阅;一次性触发的业务只需处理第三方REGISTER即可。
| 头域/IE | 取值示例 | 作用与说明 |
|---|---|---|
| Method | SUBSCRIBE | 建立事件订阅,非会话信令 |
| Request-URI | sip:[email protected] | AoR(IMPU),订阅的目标用户 |
| Event | reg |
指明订阅的是注册事件包;IMS下也可能携带3GPP扩展参数 |
| Expires | 600000 | 订阅有效期(毫秒/秒,IMS常用与注册一致的大值) |
| From / To | IMPU或P-CSCF URI | 第三方订阅时From标识订阅者;To为AoR |
| Route | S-CSCF / I-CSCF | 初始SUBSCRIBE需Route头引导至正确S-CSCF |
| Contact | 订阅者可达地址 | 用于建立dialog、回送NOTIFY |
| Accept | application/reginfo+xml | 表明可接受reginfo XML正文 |
| Content-Type | 通常无 | SUBSCRIBE一般不带正文(除非过滤规则) |
| 头域/IE | 取值/结构 | 作用 |
|---|---|---|
| Method | NOTIFY | 推送状态变更 |
| Event | reg |
对应订阅的事件包 |
| Subscription-State | active / pending / terminated | 订阅本身的状态;terminated时表明订阅结束 |
| Content-Type | application/reginfo+xml | 注册信息XML文档 |
| 正文 | reginfo XML树 | 携带registration/contact状态机快照 |
| Version | 0,1,2… | reginfo根属性,32位整数,单调递增,用于排序与丢帧检测 |
| State | full / partial | 全量还是增量 |
Subscription-State是排查订阅生命周期的关键IE:值为active表示订阅正常;terminated且带reason=参数(如timeout、deactivated、rejected)则表示订阅已被终结,订阅者应停止期待后续NOTIFY并视情况重新订阅。
NOTIFY正文是一个application/reginfo+xml文档,根元素为reginfo,下挂若干registration(每个对应一个AoR),registration下再挂若干contact。整棵树同时承载两层状态机:AoR层(init/active/terminated)与Contact层(active/terminated + event)。
flowchart TD
R["reginfo<br/>version=N, state=full|partial"]
R --> REG1["registration<br/>aor=IMPU, id=R1, state"]
R --> REG2["registration<br/>(可多AoR)"]
REG1 --> C1["contact<br/>id=C1, state=active, event=registered<br/>expires, q, callid, cseq"]
REG1 --> C2["contact<br/>id=C2, state=terminated, event=expired"]
C1 --> U1["uri: sip:ue@contact"]
C1 --> DN["display-name (可选)"]
C1 --> UP["unknown-param (RFC3261外参数)"]
style R fill:#fff3e0,stroke:#e65100
style REG1 fill:#e3f2fd,stroke:#1565c0
style C1 fill:#e8f5e9,stroke:#2e7d32
每个Contact有自己的状态机,active态下不同事件反映不同的状态迁移原因。这是reg-event包最核心、也最常考的内容:
stateDiagram-v2
[*] --> Init
Init --> Active : registered(REGISTER建)<br/>created(非SIP手段建)
state Active {
[*] --> 活跃
}
Active --> Active : refreshed(重注册)<br/>shortened(管理员缩短有效期)
Active --> Terminated : expired(超时未刷新)<br/>deactivated(撤销但可重试)<br/>probation(延迟重试)<br/>rejected(不可恢复,如欠费)<br/>unregistered(EXPIRES=0)
Terminated --> [*]
下表对9种contact event做逐一对照,是排错与业务判定的核心:
| event取值 | 触发场景 | Contact新状态 | 含义与订阅者应对 |
|---|---|---|---|
registered |
UE首次REGISTER成功 | active | 新Contact绑定,订阅者建立该Contact视图 |
created |
管理员/非SIP手段建立绑定 | active | 如OSS批量导入,需配合业务判断 |
refreshed |
UE重注册(Contact不变) | active | 仅续期,订阅者通常更新expires即可,不应重复建会话 |
shortened |
管理员缩短有效期(强制重鉴权) | active | expires属性必填,订阅者/UIE应尽快重新注册鉴权 |
expired |
Contact到期未被刷新 | terminated | 自然过期,订阅者清理该Contact |
deactivated |
管理员撤销但希望终端重注册 | terminated | 终端应尝试重新注册 |
probation |
管理员撤销且要求延迟重试 | terminated | retry-after属性必填,终端需等待后再注册 |
rejected |
管理员撤销且不接受重注册(欠费/欺诈) | terminated | 终端不应立即重试 |
unregistered |
REGISTER将Expires设为0 | terminated | 主动去注册 |
reginfo的version属性是订阅者重建一致视图的关键。订阅者本地维护一张表(按registration id、contact id索引),每收到NOTIFY比较version:
配合state=full/partial:full态下订阅者清空本地表重建;partial态下增量合并。这套"version+full/partial"机制保证了在不可靠传输下订阅者最终能收敛到与S-CSCF一致的状态——这本质上是一个最终一致性(eventual consistency)的状态同步协议。
reg只是SIP事件框架(RFC 6665)定义的众多包之一。理解它与其他包的差异,有助于在抓包与业务设计时快速定位:
| 事件包 | notifier | 订阅对象 | 正文格式 | IMS典型用途 |
|---|---|---|---|---|
reg |
S-CSCF(注册服务器) | AoR的注册状态 | application/reginfo+xml | P-CSCF/AS感知注册变化、释放资源 |
presence |
Presence服务器 | 用户出席状态 | application/pidf+xml | IMS Presence、RLS资源列表 |
dialog |
UE/AS | 会话状态 | application/dialog-info+xml | BLF(繁忙线路灯)、坐席态 |
message-summary |
消息存储 | 语音/留言计数 | application/simple-message-summary | VoLTE/VoNR语音留言通知 |
refer |
REFER接收方 | 转交事件 | - | 呼叫转交、盲转 |
conference |
会议Focus | 会议状态 | application/conference-info+xml | IMS会议、参与者增减 |
可见reg包的特殊性在于"订阅对象是网络维护的动态状态(绑定),而非终端业务状态"——这也决定了它的notifier必然是注册服务器S-CSCF。
在IMS Mw接口(CSCF间)抓包,识别reg订阅的过滤条件:
# 仅看SUBSCRIBE/NOTIFY且Event含reg
sip.Method == "SUBSCRIBE" || sip.Method == "NOTIFY"
# 进一步过滤reg包
sip.Event contains "reg"
典型成功序列(一个P-CSCF订阅周期内最少4帧):
SUBSCRIBE Event: reg (P-CSCF → I-CSCF → S-CSCF)200 OK (SUBSCRIBE应答)NOTIFY (S-CSCF → P-CSCF,带reginfo XML,首次必为full)200 OK (NOTIFY应答)打开NOTIFY帧,展开Session Initiation Protocol → Message body → reginfo,可直观看到registration.state、contact.state、contact.event等字段。Wireshark对reginfo XML有原生dissector。
| 故障现象 | 根因分析 | 排错思路 |
|---|---|---|
| 用户去注册后,P-CSCF侧IP-CAN资源不释放 | P-CSCF未订阅reg,或NOTIFY未送达 | 检查初始注册后是否有SUBSCRIBE;核对Subscription-State;查P-CSCF是否解析terminated事件 |
| 终端一直重注册风暴 | 收到shortened/deactivated但鉴权失败导致循环 |
查NOTIFY中event与expires;核对鉴权向量是否过期;检查HSS Purge原因 |
| NOTIFY收到但状态视图不一致 | version跳跃(丢帧) | 检查version递增是否连续;触发fetch(SUBSCRIBE Expires=0)拉全量 |
| 业务AS未感知注册变化 | iFC未配置或AS未订阅reg | 核对iFC中InitialFilterCriteria的Trigger Point;确认AS已发SUBSCRIBE |
| 订阅突然terminated | Subscription-State带reason=timeout/rejected | 核对Expires协商;检查鉴权/授权失败原因 |
| ## 七、设计与演进启示 |
reg-event包本质上是把"注册状态"从一次性的REGISTER握手,升级为持续可观测的状态流。这种"事件订阅+状态机推送"的模式在后续3GPP演进中被反复借鉴:5G核心网中AMF对UE可达性的订阅通知(Nudm_SDM的subscription)、UDM的data change notification,思路与之同源——都是"网络维护的动态状态需要被异步感知"。
理解reg-event,也就理解了IMS为何能实现"网络侧主动管理终端在线性"——这是VoNR/VoLTE端到端资源管理、紧急呼叫路由可达性、以及诸多AS业务编排的隐形基石。
Q1:reg事件订阅和P-CSCF的REGISTER处理是同一个流程吗? A:不是。REGISTER是UE发起的"拉取式"注册建立;reg订阅是P-CSCF在注册成功后额外发起的"推送式"事件订阅。二者串行但独立——注册成功是订阅的前提,订阅是注册状态持续可观测的保障。
Q2:为什么NOTIFY第一次必须是full state? A:订阅者(P-CSCF/AS)在订阅前对当前状态一无所知。RFC 6665强制首次NOTIFY携带全量状态,让订阅者建立"基线视图",后续partial增量才有合并的基准。没有full基线,增量NOTIFY无法解析。
Q3:shortened和deactivated有什么区别?终端该怎么做?
A:shortened发生在active态,管理员缩短了有效期但Contact仍有效(必带expires),意图是强制尽快重鉴权;deactivated使Contact进入terminated态,意图是撤销但希望重注册。前者终端续期重鉴权即可,后者终端需要重新发起完整注册。
Q4:version跳跃了怎么办? A:说明有NOTIFY丢失。订阅者应发起"fetch"——发送Expires=0的SUBSCRIBE,触发notifier回送一次full state NOTIFY,重建本地表。这是协议设计的最终一致性自愈机制。
Q5:5G架构里还有类似reg-event的机制吗? A:有且理念同源。UDM的data change notification、AMF对UE移动性/可达性变更的通知订阅,都是"网络动态状态的异步订阅-通知"。IMS的reg-event是这一思想在SIP域的经典实现。
本文由「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 等场景全覆盖。
