OmniMessage IMS 前端
OmniMessage 的 SIP 传输层 - 处理 IMS 网络中的消息进出
功能
这是一个轻量级的 SIP 前端,充当 IMS 网络与 OmniMessage 后端之间的传输层。所有消息处理、路由逻辑和业务逻辑均由 OmniMessage 处理 - 该前端仅仅:
- 接收 SIP REGISTER 消息并将订阅者数据转发给 OmniMessage
- 通过 SIP MESSAGE 接收移动发起 (MO) 短信并转发给 OmniMessage
- 从 OmniMessage 检索移动终止 (MT) 短信并通过 SIP MESSAGE 发送
- 将投递状态报告回 OmniMessage
- 处理 SIP 层协议细节(头部、确认等)
架构
IMS 前端由两个主要组件组成:
SIP 协议处理:
- SIP REGISTER - 提取订阅者数据并转发给 OmniMessage
- SIP MESSAGE - 接收 MO 短信并转发给 OmniMessage
- SIP MESSAGE - 从 OmniMessage 向订阅者发送 MT 短信
- SIP NOTIFY - 处理事件通知
- UAC 响应 - 捕获投递确认并转发给 OmniMessage
OmniMessage 后端传输层:
insert_location()- 将订阅者注册数据发送到 OmniMessageinsert_message()- 将传入的 MO 消息发送到 OmniMessageget_queue()- 从 OmniMessage 检索待处理的 MT 消息process_message()- 向 OmniMessage 发送投递状态更新frontend_register()- ��该前端注册到 OmniMessage
所有消息处理、路由决策、排队、存储和业务逻辑均在 OmniMessage 中进行。 该前端纯粹是一个 SIP 传输适配器。
配置
所有配置存储在 config.yaml 文件中。
配置参数
api_base_url - OmniMessage 后端 API 的基础 URL
- 格式:
https://hostname:port - 示例:
https://10.5.198.200:8443 - 用于所有后端 API 调用(insert_location、insert_message、get_queue 等)
location - 此 IMS 前端实例的标识符
- 格式:FQDN 风格的标识符
- 示例:
smsc01.mnc001.mcc001.3gppnetwork.org - 用于在后端系统中识别此前端
- 应在所有前端中唯一
s_cscf_sip_uri - 用于路由消息的 S-CSCF SIP URI(可选)
- 格式:
sip:hostname:port - 示例:
sip:127.0.0.2:5060 - 如果设置,所有出站 SIP MESSAGE 通过此 S-CSCF 路由
- 如果未设置,消息直接路由到 IMS 域
ims_domain - 用于订阅者路由的 IMS 域
- 格式:IMS 域名
- 示例:
ims.mnc001.mcc001.3gppnetwork.org - 用于构造订阅者地址的 SIP URI
- 当未配置 s_cscf_sip_uri 时使用
消息流
SIP REGISTER 流
移动发起 (MO) 短信流
移动终止 (MT) 短信流
轮询和刷新冷却
前端使用两种机制检查要投递的 MT 消息:
-
定期轮询 (rtimer) - Kamailio 的
rtimer模块在固定间隔(在kamailio.cfg中配置)触发Database_flush()。默认间隔为 2 秒。 -
事件驱动刷新 - 当收到的 UAC 响应与跟踪的 MT 短信不匹配(例如,MO-SMS ACK 回复)时,
Database_flush()也会立即调用。
为了防止这两种机制重叠并进行冗余的 API 调用,实施了 刷新冷却,使用共享时间戳文件 (/tmp/smsc_ims_last_flush)。每次调用 Database_flush() 时,都会将当前时间戳写入该文件。在 rtimer 触发之前,它会检查文件的修改时间 - 如果在过去的 FLUSH_COOLDOWN 秒内(默认:1 秒)发生过刷新,则跳过 rtimer 轮询。
这种共享文件的方法是必要的,因为 Kamailio 会生成多个工作进程,每个进程都有自己的 Python 解释器。实例变量在进程之间不共享,因此该���件充当跨进程共享状态。
rtimer 间隔在 kamailio.cfg 中配置:
modparam("rtimer", "timer", "name=ta;interval=2;mode=1;")