OpenSIPS通过推送通知注册时如何避免触发重复INVITE请求
OpenSIPS 重复E_UL_CONTACT_INSERT事件导致重复INVITE的解决方案
核心问题解决
你提到的fork_call路由中获取事务ID的需求可以直接实现:EBR模块在通知路由中会自动注入$avp(ebr_transaction_id)变量,该值即为触发notify_on_event的原事务ID。
方案1:事件触发层去重(推荐,兼容性最好)
通过本地缓存+分支重复校验两层逻辑,即使事件重复触发也不会生成重复INVITE分支,步骤如下:
- 先加载cachedb_local模块用于本地临时缓存:
loadmodule "cachedb_local.so" modparam("cachedb_local", "cachedb_url", "local:///")
- 调整fork_call路由逻辑:
route[fork_call] { # 读取EBR自动注入的事务ID、本次事件对应的contact URI $var(curr_tid) = $avp(ebr_transaction_id); $var(target_contact) = $avp(ebr_event_attrs.uri); $var(dup_check_key) = "invite_dup_" + $var(curr_tid) + "_" + $var(target_contact); # 缓存校验:30秒内同一事务同一contact仅处理一次 if (cache_query("local", "get " + $var(dup_check_key))) { xlog("L_INFO", "检测到重复E_UL_CONTACT_INSERT事件,跳过处理:$var(dup_check_key)\n"); exit; } cache_store("local", "put " + $var(dup_check_key) + " 1 30"); # 分支存在性校验:避免缓存失效场景下的重复注入 for($var(i)=0; $var(i)<$T_branch_cnt; $var(i)++) { if ($T_branch($var(i)/uri) == $var(target_contact)) { xlog("L_INFO", "目标contact已存在事务分支,跳过注入:$var(target_contact)\n"); exit; } } t_inject_branches("event"); }
方案2:根源减少事件触发次数
多数重复E_UL_CONTACT_INSERT事件是因为注册刷新逻辑导致,可调整registrar模块参数减少不必要的事件触发:
modparam("registrar", "skip_confirm_contact_insert", 1) # 调整未完成注册的过期时长,避免重复触发插入事件 modparam("registrar", "expire_outstanding_time", 5)
添加上述配置后,仅当实际新增未存在过的contact记录时才会触发E_UL_CONTACT_INSERT事件,相同contact的过期刷新不会重复触发事件。
内容的提问来源于stack exchange,提问作者Fulo Lin
相关产品推荐
相关产品推荐

