Kamailio通过Lua写路由

1、模块

app_lua(往往配合kimi框架一起使用)

官网参考资料:https://kamailio.org/docs/modules/5.7.x/modules/app_lua.html

2、版本选择

内置lua:支持5.1,5.2,5.3;

luajit:仅支持5.1,但是比内嵌解释器速度快很多;要求编译kam时带上:

复制代码
 $ LUAJIT="yes" make modules modules=modules/app_lua

3、支持方式

3.1、cfgengine(支持RPC重载)

模块参数设置lua脚本,所有路由功能交到lua处理,入口函数(固定)ksr_request_route,相当于原生脚本中的request_route。

复制代码
#全局参数#
cfgengine "lua"

#模块参数#
modparam("app_lua", "load", "/usr/local/kamailio/lua/route.lua")
Lua 复制代码
function ksr_request_route()
    ...
end

3.2、preload(支持RPC重载)

模块参数设置lua脚本,lua脚本中的非本地(local)方法会加载到内存中,cfg路由块中通过lua_run(func_name)调用;说明:lua脚本中local方法仍然可以被其他被暴露出来的非local调用。

cpp 复制代码
modparam("app_lua", "load", "/usr/local/kamailio/lua/route.lua")

request_route{
    ...
    lua_run("func1");
    if ($var(result) < 0) {
        exit;
    }
    ...
}
cpp 复制代码
function func1()
    ...
    KSR.pv.seti("$var(result)", -1);
    //KSR.pv.sets("$var(result)", "-1");
end

3.3、lua_dofile(不支持RPC重载)

cpp 复制代码
request_route{
    ...
    lua_dofile("/usr/local/kamailio/lua/init.lua");
    if ($var(result) < 0) {
        exit;
    }
    ...
}

3.4、lua_dosting(不涉及重载)

cpp 复制代码
lua_dostring("KSR.log([[err]], [[----------- Hello World from $fU\n]])");
lua_runstring("KSR.log([[err]], [[----------- Hello World from $fU\n]])");

4、关键技术点

4.1、返回值

暴露的几个lua_*方法的返回值,不是实际执行返回值,是脚本是否执行成功的结果,如果在lua脚本里面因为做了某些业务功能逻辑(比如查询某个数据),要把lua中的到的数据返回到主路由(main.cfg)种使用,技巧:通过伪变量来传值。

4.2、预编译

如果为了提高加载速度,可以进行提前预编译,比如:luac5.3 -o hello.lua hello,但是dofile就要去掉.lua后缀。

4.3、慢加载

当使用热加载功能事时(modparam("app_lua", "reload", 1)),并不是立刻更新lua文件,每次更新对于的version会加1,当真正执行到脚本时,比较发现两个version不同,此时才加载;具体为:

app_lua模块在内存中维护了一个list列表,里面存放load进来的lua【modparam("app_lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")】"信息"(关键是存放了每条数据的version信息),每次reload,version加1,启动时初始化为0,version信息也会在脚本对象中存放一份,每次执行脚本时,会比较脚本对象中的version与list中是否一致。不一致则更新lua,同时更新脚本对象中version的值。

4.4、加载方法

语法:kamcmd app_lua.reload <index>

cpp 复制代码
...
    kamcmd app_lua.reload 0
...

index的需要通过另外一个rpc命令获取,app_lua.list

相关推荐
夏幻灵5 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
程序猿编码5 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
bkspiderx6 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆7 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光7 小时前
C语言入门,深入理解指针(3)
c语言·开发语言
码云数智-园园7 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
禾小西8 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨8 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
徐小黑ACG9 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
hz567899 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件