今天笔者来给大家讲一下KamailioRPC和OpenSIPSMI的一些小区别。
以查找注册用户的信息为例,Kamailio的命令如下:
代码语言:javascript复制kamcmd ul.lookup location 1001@192.168.100.173
代码语言:javascript复制{
AoR: 1001
Contacts: {
Contact: {
Address: sip:1001@192.168.1.122:9999;transport=udp
Expires: 2949
Q: -1
Call-ID: 61A34281A03EAD774B7CE87E3D1C009B@192.168.100.173
CSeq: 2
User-Agent: Kapanga Softphone Desktop Windows 1.00/2180b 1654855613_88A4C2D0E069_0A002700000D_508492987BAA_508492987BAB_528492987BAA
Received: sip:192.168.1.122:9999
Path: [not set]
State: CS_SYNC
Flags: 0
CFlags: 64
Socket: udp:192.168.100.173:5060
Methods: 16383
Ruid: uloc-6350e6b4-70a-1
Instance: [not set]
Reg-Id: 0
Server-Id: 0
Tcpconn-Id: -1
Keepalive: 0
Last-Keepalive: 1666246840
KA-Roundtrip: 0
Last-Modified: 1666246840
}
}
}
而OpenSIPS的命令是:
代码语言:javascript复制opensips-cli -x mi ul_show_contact location 1001@192.168.100.173
代码语言:javascript复制DEBUG: Loaded module 'mi'
DEBUG: sent command ':opensips_fifo_reply_22563:{"jsonrpc": "2.0", "id": "21695", "method": "which", "params": []}'
DEBUG: reply file '/tmp/opensips_fifo_reply_22563'
DEBUG: running in non-interactive mode mi ul_show_contact ['location', '1001@192.168.100.173']
DEBUG: running command 'ul_show_contact' '['location', '1001@192.168.100.173']'
DEBUG: positional parameters are used
DEBUG: 0. ['location', '1001@192.168.100.173']
DEBUG: running command 'ul_show_contact' '['location', '1001@192.168.100.173']'
DEBUG: sent command ':opensips_fifo_reply_30177:{"jsonrpc": "2.0", "id": "16856", "method": "ul_show_contact", "params": ["location", "1001@192.168.100.173"]}'
DEBUG: reply file '/tmp/opensips_fifo_reply_30177'
{
"AOR": "1001",
"Contacts": [
{
"Contact": "sip:1001@192.168.1.122:9999;transport=udp",
"ContactID": "3784999887725085067",
"Expires": 2963,
"Q": "",
"Callid": "7922F7BEA5AB8F92EE0AA287B27AB56F@192.168.100.173",
"Cseq": 2,
"User-agent": "Kapanga Softphone Desktop Windows 1.00/2180b 1654855613_88A4C2D0E069_0A002700000D_508492987BAA_508492987BAB_528492987BAA",
"Received": "sip:192.168.1.122:9999",
"State": "CS_SYNC",
"Flags": 0,
"Cflags": "NAT",
"Socket": "udp:192.168.100.173:5060",
"Methods": 16383
}
]
}
无论传递的参数还是返回的结果,二者都非常相似。
其中Cflags保存的是分支标志,上面的例子Kamailio的分支标志是64,一般在Kamailio.cfg的开头几行能找到这样的定义:
代码语言:javascript复制#!define FLB_NATB 6
这是处理用户注册的路由脚本:
代码语言:javascript复制route[REGISTRAR] {
if (!is_method("REGISTER")) return;
if(isflagset(FLT_NATS)) {
setbflag(FLB_NATB); /* 如果运行到这里,ul.lookup看到的Cflags就是64, 1左移6,正好是64*/
}
if (!save("location")) {
sl_reply_error();
}
exit;
}
OpenSIPS的分支标志是字符串,处理用户注册的路由脚本一般是:
代码语言:javascript复制 if (nat_uac_test(23)) {
if (is_method("REGISTER")) {
fix_nated_register();
setbflag("NAT"); /* 如果运行到这里,ul_show_contact看到的Cflags就是NAT */
} else {
fix_nated_contact();
setflag("NAT");
}
}
对于Kamailio,Ruid是主键,而对于OpenSIPS,contact_id是主键。
Kamailio的usrloc模块可以配置KeepAlive参数,服务器周期性探测客户端是否在线,这样Contact里面多了几个跟KeepAlive有关的参数。OpenSIPS的usrloc模块暂时没有这个功能。
上面给的都是外部程序调用,但其实在路由脚本里面调用Kamailio的RPC或者OpenSIPS的MI,都是很方便的。下面给出例子:
kamailio.cfg:
代码语言:javascript复制 $var(aor) = $tU "@" $td;
$var(req) = '{"jsonrpc":"2.0","method":"ul.lookup","params":["location", "$var(aor)"],"id":1}';
jsonrpc_exec("$var(req)");
xlog("code = $jsonrpl(code)n");
xlog("body = $jsonrpl(body)n");
opensips.cfg:
代码语言:javascript复制 /* 需要loadmodule "mi_script.so" */
/* 需要loadmodule "json.so",解析结果 */
$var(aor) = $tU "@" $td;
$avp(params) = $var(aor);
$avp(params) = "location";
mi("ul_show_contact", $var(data), $avp(params));
xlog("data = $var(data)n");
需要注意的是,avp变量是以堆栈形式保存数据的,因此aor要放前面,接着是location,传到usrloc模块进行处理的时候参数正好反过来,location在前,aor在后。
以上代码在Kamailio5.5.5和OpenSIP3.2.8下测试通过。