news 2026/2/8 10:02:54

Kamailio 的 select 框架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kamailio 的 select 框架

选择框架

(作者:米哈尔·马蒂斯卡)

你可能会问,选择框架究竟为何会被引入?最主要的原因是,以往每当你需要检查入站消息的任意部分(如消息头)时,都必须编写新的模块或新的函数来实现该功能。此外,受历史局限性的影响,这类函数最多只能接收两个参数。若需要传入更多参数,就必须采用变通方案:先设置好相关属性,再由该函数对属性进行校验。因此,为了让路由脚本更具可读性和易懂性,一种全新的功能组件——选择框架,应运而生并得到了支持。

在脚本中,每个选择项都通过其唯一名称来标识。设计这种标识符的初衷,是让它的含义尽可能直观易懂。例如,当你看到@to.uri.user时,就能立刻明白它的作用是从To消息头所包含的URI中提取用户名。在脚本里,无论你在何处看到选择项标识符,它所代表的实际上都是对应的值,这个值会在路由脚本的执行过程中被调用。

为了保证选择框架的执行效率,选择项标识符会在SER启动阶段完成解析和固化。如果标识符无效,系统会输出错误信息,且SER将无法启动。而在请求路由脚本的执行阶段,仅需发起一次函数调用——如果该调用需要用到选择项标识符,就会将解析后的标识符作为参数传入。从性能角度来看,调用某个模块中的专用函数,与调用代表选择项标识符的函数,二者几乎没有差异。

工作原理概述

我们所说的选择项,本质上是一种标准化调用方式,用于调用那些在SER内核或各类模块中被定义为“选择函数”的方法。选择项标识符以@符号开头,由若干文本元素组成,元素之间用英文句点.分隔;部分场景下,还可以在方括号[]内添加单个整数或字符串作为参数。

选择项可在路由脚本的以下场景中使用:

  1. 表达式求值过程中;
  2. 作为属性赋值操作的右值;
  3. 作为部分函数的调用参数(此用法仅适用于支持该特性的函数,且参数必须是包含选择项标识符的文本,因此需要用双引号括起来)。

此外,在Xlog日志格式化功能中,选择项也可作为组成最终日志内容的元素,其格式为%@select.identifier.as.usual

选择函数的返回值为文本字符串,但需要注意的是,在以下两种情况下,返回值也可能是长度为0的空字符串:一是该空值本身是合法的(例如某些URI参数允许为空);二是选择函数在消息头中未找到目标值,或在解析消息时遇到语法错误。这类异常情况会对条件表达式产生影响——只要选择项的求值过程出现错误,无论其结果是否为空字符串,条件表达式的最终判断结果都会为false

选择项标识符规则

选择项标识符以@符号开头,后接至少1个、最多30个文本元素,元素之间用英文句点.分隔。标识符的元素大小写不敏感,你可以通过大小写区分来突出某些元素,但建议优先使用小写形式。

部分选择函数支持传入参数(例如重复消息头的索引、消息头名称或鉴权域),这类参数需要放在方括号[]内,嵌入到标识符中。参数索引从1开始计数(程序员需特别注意这一点),这种设计更符合直观认知;同时,你也可以使用负数索引表示反向计数,例如用-1表示获取最后一个消息头。

合法的标识符示例

@the.simplest @another.with!["parameter"] @yet.another![1].parameter![2] @you.can.also.mix.string!["like-this"].and.integer![1].parameters

嵌套选择项

你可能会发现SIP请求中存在一些重复的模式,例如许多SIP消息头中都包含URI元素。选择框架支持复用内核中已有的URI解析器和选择函数(也可以是参数值解析器,包括消息头参数或URI参数解析器,或是其他你能想到的解析器),并将其作用于选择项的中间结果,以此简化开发流程。

这种用法被称为嵌套选择项(如果感兴趣,可参考开发者文档),它会将一次选择项调用拆分为两次(或多次)独立的函数调用:第一次调用会返回URI文本作为临时结果,随后该临时结果会被传入内置的URI选择处理机制,最终生成目标结果。

例如,@hf_value!["X-any-header"].nameaddr.uri.user的执行逻辑为:

  1. 提取X-any-header消息头的值;
  2. 假设该值符合RFC规范中对name-addr格式的定义,将其传入name-addr选择解析器;
  3. 解析器从URI中提取用户名,并将其作为该选择项的最终返回值。

所有返回URI的选择项结果,都可以传入专门的URI选择函数,从而访问URI的各个组成部分。

以下选择项均可返回对应的URI:
@request_uri@dst_uri@next_hop@from.uri@to.uri@refer_to.uri@rpid.uri@contact.uri@record_route.uri,以及@hf_value!["any-header"].nameaddr.uri

若只需获取用户名,只需在选择项标识符后追加.user即可。无论第一步获取的是哪一个URI,.user这个标识符后缀的含义和用法都是完全相同的。

URI嵌套选择项标识符列表

标识符功能说明
type返回标准化(小写)的URI类型,例如sipsipsteltels
user返回URI中的用户名
pwd返回URI中的密码
host返回URI中的主机地址
port返回URI中的端口号(以上标识符的功能均通俗易懂)
transport返回URI中transport参数的值;若该参数不存在,则返回基于URI类型的默认传输协议
hostport返回URI中的主机:端口组合值;若端口未指定,则使用基于URI类型的默认端口
params返回URI中的完整参数部分,例如user=phone;phone-context=+1234
params!["parameter-name"]返回URI中指定参数的值

选择项在表达式中的应用

选择项可用于条件表达式,常见用法如下:

  1. 非空判断

    if (@select.value) {...}

    当选择项返回非空字符串时,条件判断结果为true

    注意:这种用法已被废弃,SER启动时会输出警告信息。在Sip-router中,该写法的逻辑变为:仅当返回值为非空且非零的数字字符串(如"123")时,条件才为true
    推荐使用标准写法:

    if (@select.value!="")

    if (!strempty(@select.value))
  2. 等值判断

    if (@select.value=="string") {...} if ("string"==@select.value) {...}

    当选择项求值过程无错误,且返回值与"string"完全相等时,条件为true。表达式右侧可以是任意值(包括AVP变量、PV变量或其他选择项),而非仅限于常量。

  3. 不等值判断

    if (@select.value!="string") {...} if ("string"!=@select.value) {...}

    用于判断两个字符串是否不相等。若选择项求值过程出错,条件判断结果也会为false

  4. 正则匹配

    if (@select.value=~"reg.*expr.?") {...}

    当选择函数返回的字符串匹配指定正则表达式时,条件为true注意:该运算符的左右操作数顺序不可随意调换,例如:

    if ("string"=~@select.value) {...}

    其逻辑是判断固定字符串"string"是否匹配选择项返回值作为正则表达式的规则,这通常不符合实际需求。

选择项可用于任意类型的表达式中,包括赋值操作的右值、if条件判断、while循环条件或switch分支判断等。
示例:

$attribute=@the.select.you.want

选择项在函数参数中的应用

部分函数支持将选择项的返回值作为调用参数,但该特性仅适用于明确支持此功能的函数。这类函数的参数会存储选择项标识符,函数会在SER启动阶段负责解析并固化该标识符,在运行阶段调用对应的选择函数以获取参数值。

若选择项求值过程出错,函数会返回false,且函数后续的执行逻辑通常会被跳过。

系统选择项

随着选择框架的优势逐渐显现,开发者开始探索更多可通过选择项访问的功能,系统选择项便是其中之一。这类选择项的标识符均以@sys开头,例如:

  • @sys.pid:返回当前进程ID的字符串形式
  • @sys.now:返回Unix时间戳
  • @sys.utc:返回UTC时间戳(适用于多时区场景)
  • @sys.unique:生成并返回一个随机的UUID(版本2)

模块中的选择项

选择框架是一种功能强大的工具,且可通过SER的模块机制轻松扩展。以TLS模块为例:脚本中需要获取或校验的大量TLS相关信息,都需要依赖TLS模块才能实现。因此,所有与TLS相关的选择项都隶属于TLS模块——当你加载该模块后,这些选择项即可使用;若未加载模块,SER会因检测到无效的选择项标识符而拒绝启动。

从使用角度来看,模块提供的选择项与内核原生的选择项并无差异,你无需关心选择项的具体来源,只需确保已加载所有必需的模块即可。

选择项完整列表

关于Sip-router开发版本(主分支)中已定义的所有选择项,可参考官方文档:http://sip-router.org/docbook/sip-router/branch/master/select_list/select_list.html。


追踪:• 选择项

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 18:08:13

构建 OpenHarmony 简易密码强度指示器:用字符串长度实现直观反馈

一、为什么需要“简易密码强度指示器”? 在 OpenHarmony 的账户注册、设备配对或应用登录场景中,用户常需设置密码。但许多界面仅显示“密码至少 8 位”,缺乏即时、直观的反馈,导致: 用户反复尝试;设置弱…

作者头像 李华
网站建设 2026/2/6 1:27:28

小米MiMo-V2-Flash深度解析:国产开源大模型标杆+一步API接入全指南

前言:2025年小米推出的MiMo-V2-Flash大模型,以3090亿参数基座150亿活跃参数的轻量化设计,打破了“重参数即强性能”的行业误区,成为国产开源大模型的标杆产品。其不仅在长文本处理、编程推理等核心能力上跻身第一梯队,…

作者头像 李华
网站建设 2026/2/7 14:33:40

GMV Max冷启动是什么TikTok Shop新手防断流爆单攻略

作为 TikTok Shop 新手,你可能会遇到这样的困惑:广告投放才上线没多久,流量就断了,ROI 上下波动巨大,甚至新品几乎跑不动。这并非系统针对或限流,而是 GMV Max 的冷启动机制在发挥作用。 本文章教你快速理解…

作者头像 李华
网站建设 2026/2/5 23:49:03

多模态大模型+RAG实战:工业缺陷智能识别系统全解析

该系统整合多模态大模型与RAG技术,实现工业、能源、交通等领域设备缺陷的高精度识别与诊断。多模态模型融合文本、图像、视频、音频等多源数据,RAG动态检索外部知识库提升诊断准确性。系统具备高精度识别、实时高效、强环境适应性等优势,已在…

作者头像 李华
网站建设 2026/2/8 9:22:02

智能计算芯知识:大模型开发者必学的AI专家路线图与700+专业资料

文章介绍了"智能计算芯知识"知识星球平台提供的AI、芯片、半导体等领域专业资源,重点详述了AI专家路线图及其5个学习分支:数据科学家、机器学习、深度学习、数据工程师和大数据工程师路线图。这些路线图涵盖从基础概念到高级应用的全套知识体系…

作者头像 李华
网站建设 2026/2/5 10:40:22

收藏这份2026年大模型薪资攻略:从入门到高薪,小白也能抓住AI红利

2025年AI大模型领域薪资诱人,大模型算法工程师月薪7万,AI科学家月薪11万。人才供需失衡、政策支持和技术红利窗口期是高薪主因。文章详细介绍了5大高薪岗位必备技能、6个涨薪策略和需避坑点,并提供了从初阶应用到商业闭环的系统化学习路径。未…

作者头像 李华