前情提要:
在文章 freeswitch+freeswitch+语音网关拨打电话 中配置了多个网关。
当前的做法:在
/usr/local/freeswitch/conf/dialplan/public.xml
使用destination_number
的尾号去进行匹配<condition field="destination_number" expression="^(\d*[02468])$">
这种做法存在的问题:
符合规则的尾号不能被同时打,因为一个网关只能支持拨打一个电话
解决方案:
在《FreeSWITCH权威指南》一书中,有一个通过Lua脚本多个网关循环外呼的案例
编写lua脚本
在freeswitch/script
文件夹下编写auto_retry_gw.lua
脚本
lua
retries = 0
bridge_hangup_cause = 0
gateways = {
{
name = "gw2", -- 第一个网关名称
caller_id_number = "559947", -- 网关1的主叫号码
caller_id_name = "559947" -- 网关1的主叫名称
},
{
name = "gw3", -- 第二个网关名称
caller_id_number = "559948", -- 网关2的主叫号码
caller_id_name = "559948" -- 网关2的主叫名称
},
{
name = "gw4", -- 第三个网关名称
caller_id_number = "559944", -- 网关3的主叫号码
caller_id_name = "559944" -- 网关3的主叫名称
},
{
name = "gw5", -- 第四个网关名称
caller_id_number = "559945", -- 网关4的主叫号码
caller_id_name = "559945" -- 网关4的主叫名称
},
{
name = "gw6", -- 第四个网关名称
caller_id_number = "559946", -- 网关4的主叫号码
caller_id_name = "559946" -- 网关4的主叫名称
}
-- ... 可以继续添加更多网关配置
}
-- 呼叫的号码
dest = argv[1]
-- 循环外呼
function call_retry()
freeswitch.consoleLog("notice", "Calling [" ..dest.. "] FROM lua\n")
retries = retries + 1
if not session.ready() then
return;
end
-- 设置主叫号码
session:setVariable("effective_caller_id_number", gateways[retries].caller_id_number)
session:setVariable("effective_caller_id_name", gateways[retries].caller_id_name)
-- 拼接呼叫字符串
dial_string = "sofia/gateway/" ..gateways[retries].name .. "/" ..dest;
freeswitch.consoleLog("notice", "Dialing [" ..dial_string.. "]\n");
session:execute("bridge", dial_string);
bridge_hangup_cause = session:getVariable("bridge_hangup_cause") or session:getVariable("originate_disposition");
-- NORMAL_CLEARING 表示除了正常接通,都去循环呼叫
if(retries < 4 and bridge_hangup_cause ~= "NORMAL_CLEARING") then
freeswitch.consoleLog("notice", "On calling [" ..dial_string.. "] hangup. Cause:[" ..bridge_hangup_cause.. "].Retry: " ..retries.. "\n");
session.sleep(1000);
call_retry();
else
freeswitch.consoleLog("notice", "Retry Exceed, Now hangup!\n");
end
end
session:preAnswer();
-- 有了这两个配置表示一个呼叫失败,继续呼叫下一个
session:setVariable("hangup_after_bridge", "true");
session:setVariable("continue_on_fail", "true");
call_retry();
在fs_cli中测试lua脚本
bash
-- 需要使用下面的命令测试
originate {dest=017858661999}loopback/1234 &lua(test.lua)
- &lua(test.lua 017858661999) 的方式行不通,会接收不到
- lua test.lua 017858661999 能接收到,但是session会为空
- 获取dest的方式修改为
dest = session:getVariable("dest")
在拨号计划中使用
将/usr/local/freeswitch/conf/dialplan/public.xml
中的拨号计划配置修改为如下图:

优化方向
把正在通话的号码加入到内存hash中,这样可以减少判断次数