wandoubaba / 2023-06-01
我们在用FreeSWITCH开发电话群呼功能时,少不了需要测试,用什么方法测试呢?准备一批真实的被叫号码肯定是不现实了。其实我们完全可以准备另外一台专门用来“接听”电话的FreeSWITCH,可以把开发机或测试机上的FreeSWITCH发起的外呼全部都送到这台专门用来接听电话的FreeSWITCH上,具体怎么送?比如被叫FreeSWITCH的主机名是fs40吧,那么我们就在主叫FreeSWITCH上做一个名叫“to40“的gateway就好了,用to40网关做群呼测试,那么所有的呼叫就都会送到fs40这个FreeSWITCH上了。
接下来,问题又来了,当被叫发现来电话了之后,可能会接听吧,也有可能会拒接吧,接听后可能会在听几秒后挂断电话吧,那么我们是不是可以在被叫FreeSWITCH上模拟出这种随机性呢?
当然,我们就在被叫FreeSWITCH上用一个lua脚本实现随机接听或拒接、接听随机时长后主动挂断电话的功能。
在FreeSWITCH安装目录的
scripts
目录下创建脚本文件,假设文件名为
random_answer.lua
,脚本内容:
--[[
这是一个模拟被叫的脚本
可按照指定比率接听或拒接电话
接听电话后可在随机时间后挂断电话
接听电话后执行echo应用
接听电话后保存mp3通话录音
]]
-- 随机决定 answer 或 reject
local function random_call()
-- 随机决定 answer 或 reject
local random_number = math.random(1, 3) -- 生成 1-3 的随机数
if random_number ~= 1 then -- 66.7% 的概率 answer
-- 设置最长时间
-- 生成 1-25 的随机数作为会话的最长时间
local session_term = math.random(1, 25)
-- 延迟 随机 秒钟后挂断通话
session:execute("sched_hangup", "+" .. session_term)
-- 设置录音文件名
local record_time = os.time()
local record_dir = os.date("%Y%m%d", record_time)
local record_filename = os.date("%Y%m%d%H%M%S", record_time).."-"..session:getVariable("caller_id_number").."-"..session:getVariable("destination_number")..".mp3"
session:execute("record_session", "$${recordings_dir}/"..record_dir.."/"..record_filename)
-- 接听电话
session:answer()
-- 执行echo
session:execute('echo')
else -- 33.3% 的概率 reject
freeswitch.consoleLog("info", "Reject call\n")
session:execute("respond", "486")
end
end
-- 执行随机决定
() random_call
如果我们在主叫FreeSWITCH上通过external方式实现的把呼叫全部送到被叫FreeSWITCH上,那么我们就要在被叫FreeSWITCH上做pulbic的拨号计划;而如果我们是让主叫FreeSWITCH做为被叫FreeSWITCH的一个注册分机的话,就要在被叫FreeSWITCH的default中做拨号计划。
这里我们以public为例,在conf/dialplan/public
中创建一个名为random_answer.xml
的文件,文件内容如下:
include>
<extension name="random_answer">
<<!-- 假设约定被叫号码以000开头的都是测试电话 -->
condition field="destination_number" expression="^000(.*)$">
<action application="lua" data="random_answer.lua"/>
<condition>
</extension>
</include> </
在fs_cli
中执行reloadxml
,使配置生效。
需要在主叫FreeSWITCH做一个可以送到被叫FreeSWITCH的gateway,在conf/sip_profiles/external
中创建名为call_test.xml
的文件,内容如下:
<?xml version='1.0' encoding='utf-8'?>
include>
<gateway name="to40">
<param name="username" value="to40" />
<param name="realm" value="被叫FS的地址" />
<param name="proxy" value="被叫FS的地址:external端口号" />
<param name="register" value="false" />
<param name="expire-seconds" value="60" />
<param name="retry-seconds" value="60" />
<gateway>
</include> </
在主叫FreeSWITCH的fs_cli中执行sofia profile external rescan
使新建的gateway生效。
先用originate命令发一个外呼试一下:
freeswitch@debian> bgapi originate {ignore_early_media=true}sofia/gateway/to40/00088 &playback($${hold_music})
正常情况下我们应该能在被叫FreeSWITCH的日志或控制台中看到来电记录,多外呼几次,我们可以看到,有的电话被接听,有的电话被拒接,被接听的电话都会在持续了一个随机时长后由被叫挂断,说明我们的这个模拟被叫的FreeSWITCH已经做好了。
如果主叫发起呼叫的并发量很大的话,我们就要把被叫FreeSWITCH的允许并发会话数调大,否则就会出现“呼损”的情况,当然,“呼损”现象也是群呼的一种结果,也是需要应对的。