XSwitch进阶文档
XSwitch怎么编写xlonglive脚本
xlonglive
即万岁
脚本,指的是一系列长期运行在XSwitch
内部的lua
脚本,你可以在脚本内订阅FreeSWITCH
产生的事件,从而驱动你的脚本去做你想做的事情。
由于lua
内没有类的概念,因此我们使用表与原表的形式,实现了一个假类,如:
---@class xlonglive local xlonglive = {} xlonglive.new = function(name) local self = { name = name, event_name = "xlonglive::" .. name, } setmetatable(self, { __index = xlonglive }) return self end
以上代码表示在其他脚本中调用xlonglive.new('test')
时,会生成一个表,其中包含name
,值为test
;还包含event_name
,值为xlonglive::test
。并使用setmetatable
设置表的元素。
示例
假设新建一个my_test.lua
的xlonglive
脚本,内容如下:
1 -- 获取lua一些环境信息 2 local cur_dir = debug.getinfo(1).source; 3 cur_dir = string.gsub(debug.getinfo(1).source, "^@(.+/)[^/]+$", "%1") 4 if cur_dir:sub(1,1) == '/' then -- plain Lua 5 package.path = package.path .. ";/etc/xtra/?.lua" 6 package.path = package.path .. ";" .. cur_dir .. "?.lua" 7 package.path = package.path .. ";" .. cur_dir .. "vendor/?.lua" 8 end 9 -- 获取XSwitch内部工具函数组件 10 local utils = require 'utils' 11 -- 和获取XSwitch config.lua内的配置组件 12 local config = require 'xtra_config' 13 -- 获取XSwitch连接数据库组件 14 local xdb = require 'xdb' 15 16 -- 新建连接数据库实例 17 local dbh = xdb.new() 18 if config.db_auto_connect then dbh:connect(config.fifo_cdr_dsn or config.dsn) end 19 20 -- 声明本lua脚本 21 xlonglive = (require 'xlonglive').new('my_test') 22 23 -- 根据argv[1]来决定具体的动作,其值可以为stop/start/check/purge 24 if not xlonglive:start(argv[1]) then 25 goto donedone 26 end 27 28 function recv_heartbeat(event) 29 freeswitch.consoleLog("INFO", "so good, we received a HEARTBEAT event!\n") 30 end 31 32 -- 在FreeSWITCH内打印一行日志 33 freeswitch.consoleLog("INFO", "BINDING to HEARTBEAT\n") 34 35 -- 订阅HEARTBEAT事件 36 con = freeswitch.EventConsumer("HEARTBEAT") 37 -- 订阅xlonglive产生且名为`xlonglive::my_test`的事件 38 con:bind('CUSTOM', xlonglive.event_name) 39 40 -- 开始循环取事件 41 while true do 42 ::continue:: 43 -- 一直阻塞等待下一个订阅事件的产生 44 local event = con:pop(1) 45 -- pop超时1秒,若1秒内未收到订阅的事件,则继续向下进行 46 -- local event = con:pop(1, 1000) 47 -- 以上两种pop任选其一即可 48 49 if event and event:getHeader("Event-Subclass") == xlonglive.event_name then 50 -- 获取到xlonglive产生的事件, Event-Subclass是"xlonglive::my_test" 51 local action = event:getHeader('Action') 52 -- xlonglive产生的rpc事件,可通过xlonglive:new_rpc_event(method)生成 53 if action == 'rpc' then 54 reply = xlonglive:new_rpc_reply_event(event) 55 reply:addBody("Reply Body") 56 freeswitch.consoleLog("INFO", reply:serialize()) 57 reply:fire() 58 end 59 if not xlonglive:check(event) then 60 -- 若收到停止脚本事件,则退出循环 61 freeswitch.consoleLog("INFO", "Stopping my_test ...\n") 62 break 63 end 64 goto continue 65 end 66 67 -- 调用自定义函数,打印一行日志 68 recv_heartbeat(event) 69 end 70 71 -- 取消事件订阅 72 con:cleanup() 73 74 -- 释放数据库链接 75 if dbh then 76 dbh:release() 77 end 78 79 freeswitch.consoleLog("INFO", "my_test script down\n") 80 ::donedone::
运行
默认XSwitch
自带的xlonglive
脚本位于XSwitch
容器内的/usr/local/freeswitch/xui/lua/xui/xui/xlonglive
目录下,你可将自己的脚本放在XSwitch
容器内的任何位置。
假设本次my_test.lua
脚本放置于XSwitch
容器内的/usr/local/freeswitch/xui/lua/xui/xui/xlonglive
目录下。
启动
启动时,脚本将一直处于while
循环内等待事件的产生。同时xlonglive
会向FreeSWITCH
内的xui hash
表插入一条数据,key
为xlonglive-my_test
,value
为1
,此动作是为后续检查脚本是否运行做准备。
进入fs_cli
前台,执行如下命令:
luarun /usr/local/freeswitch/xui/lua/xui/xui/xlonglive/my_test.lua start
有如下输出,则表示脚本启动成功:
2024-02-04 08:36:28.917391 98.87% [INFO] switch_cpp.cpp:1477 BINDING to HEARTBEAT 2024-02-04 08:36:28.917391 98.87% [DEBUG] switch_cpp.cpp:86 bound to HEARTBEAT 2024-02-04 08:36:28.917391 98.87% [DEBUG] switch_cpp.cpp:86 bound to CUSTOM xlonglive::my_test
以后每隔20秒,你写的xlonglive
脚本就会向FreeSWITCH
输出一行日志,如下:
2024-02-04 08:36:41.152365 98.60% [INFO] switch_cpp.cpp:1477 so good, we received a HEARTBEAT event! 2024-02-04 08:37:01.233497 98.63% [INFO] switch_cpp.cpp:1477 so good, we received a HEARTBEAT event! 2024-02-04 08:37:21.372955 98.63% [INFO] switch_cpp.cpp:1477 so good, we received a HEARTBEAT event!
检查
若你不清楚my_test.lua
是否已经通过xlonglive
启动,可进入fs_cli
前台,执行如下命令:
luarun /usr/local/freeswitch/xui/lua/xui/xui/xlonglive/my_test.lua check
若有如下输出,则表示该脚本已经正在运行:
2024-02-04 08:38:43.552360 98.57% [ERR] switch_cpp.cpp:1477 my_test Already Running -ERR key already exists 2024-02-04 08:38:43.552360 98.57% [INFO] switch_cpp.cpp:1477 =?:0: my_test is running
若脚本未运行,则此命令的执行结果与start
相同,即启动脚本。
停止
若你想停止my_test.lua
脚本,可进入fs_cli
前台,执行如下命令:
luarun /usr/local/freeswitch/xui/lua/xui/xui/xlonglive/my_test.lua stop
有如下输出,则表示脚本停止成功:
2024-02-04 08:41:12.795791 98.63% [INFO] switch_cpp.cpp:1477 Stopping my_test ... 2024-02-04 08:41:12.795791 98.63% [DEBUG] switch_event.c:2507 Event Binding deleted for src/switch_cpp.cpp:HEARTBEAT 2024-02-04 08:41:12.795791 98.63% [DEBUG] switch_event.c:2507 Event Binding deleted for src/switch_cpp.cpp:CUSTOM 2024-02-04 08:41:12.795791 98.63% [INFO] switch_cpp.cpp:1477 my_test script down
若你想停止一个没有运行中的xlonglive
脚本,则此命令将无任何输出。
此停止只是告知你的my_test.lua
脚本退出while
循环(见my_test.lua
L59-L63),但仍未删除xui hash
表内的数据。
清理
清除xui hash
表内关于my_test.lua
的数据。
注意,若脚本正在运行中,执行此动作,则只会清除hash内的数据,而不会停止脚本