FreeSWITCH 呼出之我见

少量呼出,不在本文讨论之列

如果是我来实现批量呼出,那么可能是这样:

先建一张数据库的表,字段有:

id 自增加,主键

caller varchar 主叫号码

called varchar 被叫号码

service varchar 业务相关字段

uuid varchar channel-uuid,如果为空,那么调用 fs_cli -x 'create_uuid'

done int  是否已完成

然后起一个 taskloop.lua 进行处理:

每秒处理一次

调用 status 查看

如果当前 channels 数超过某个阈值,则退出

如果当前 sps 超过某个阈值,则退出

调用 fsapi 呼出,并写回数据库的表

回头给出 taskloop.lua 的具体内容


讨论另外一个问题:

fs --- 语音网关 --- 运营商

运营商说,语音网关发送 INVITE,每个源端口有 30 sps 的限制,比如:

语音网关 5060   --- 运营商

语音网关 5062  --- 运营商

语音网关 5064  --- 运营商

语音网关 5066  --- 运营商

如上图所示,这样就能做到 120 sps

那么要怎样配置呢?

非常简单呀!

比如在 fs 起多个 SIP Profile:

<profile name="external0">
  <gateways>
    <X-PRE-PROCESS cmd="include" data="gw/wgw1.xml"/>
  </gateways>
  <param name="rtp-ip" value="$${local_ip_v4}"/>
  <param name="sip-ip" value="$${local_ip_v4}"/>
  <param name="sip-port" value="5060"/>
  ...  
</profile> 


<profile name="external1">
  <gateways>
    <X-PRE-PROCESS cmd="include" data="gw/gw2.xml"/>
  </gateways>
  <param name="rtp-ip" value="$${local_ip_v4}"/>
  <param name="sip-ip" value="$${local_ip_v4}"/>
  <param name="sip-port" value="5062"/>
  ...  
</profile> 

<profile name="external2">
  <gateways>
    <X-PRE-PROCESS cmd="include" data="gw/gw3.xml"/>
  </gateways>
  <param name="rtp-ip" value="$${local_ip_v4}"/>
  <param name="sip-ip" value="$${local_ip_v4}"/>
  <param name="sip-port" value="5064"/>
  ...  
</profile> 

<profile name="external3">
  <gateways>
    <X-PRE-PROCESS cmd="include" data="gw/gw4.xml"/>
  </gateways>
  <param name="rtp-ip" value="$${local_ip_v4}"/>
  <param name="sip-ip" value="$${local_ip_v4}"/>
  <param name="sip-port" value="5066"/>
  ...  
</profile> 

4 个 SIP Profile,其中每个 Profile 对应一个网关,所有的这些网关都指向同一个语音网关

接着就是 distributor 的配置,非常简单:

<configuration name="distributor.conf" description="Distributor Configuration">
  <lists>
    <list name="testdist">
      <node name="gw1" weight="1"/>
      <node name="gw2" weight="1"/>
      <node name="gw3" weight="1"/>
      <node name="gw4" weight="1"/>
    </list>
  </lists>
</configuration>

最后是拨号字符串的配置

以前这样写:

originate sofia/gateway/gwxx/1234567 &echo

现在调整为:

originate sofia/gateway/${distributor(testdist)}/1234567 &echo

除了用 fs mod_distributor 之外是否还有别的办法呢?

换我上的话我肯定用 Kamailio,控制起来比较方便


建表(PostgreSQL):

CREATE TABLE dialtasks (
    id SERIAL PRIMARY KEY NOT NULL,
    uuid VARCHAR DEFAULT '',
    caller VARCHAR NOT NULL,
    called VARCHAR NOT NULL,
    service VARCHAR NOT NULL,
    done INTEGER DEFAULT 0  
);

插入测试数据:

insert into dialtasks(caller, called, service)  values ('1234567', '777777', 'foo');


taskloop.lua 的内容可以是:

local dsn = "odbc://freeswitch"
-- local dsn = "pgsql://hostaddr=127.0.0.1 port=5432 dbname=freeswitch user=freeswitch password='****'"
local json = freeswitch.JSON()
local api = freeswitch.API()
local dbh = freeswitch.Dbh(dsn)
local config = {}
-- 根据具体情况进行修改
config.limit = 10
config.sps = 30
config.maxchannels = 1000
config.gw = "gw1" -- 或者用 distributor

function debug(s)
	freeswitch.consoleLog("ERR", (s or "nil") .. "\n")
end

function serialize(o)
	local s = ""

	if type(o) == "number" then
		s = s .. o
	elseif type(o) == "string" then
		s = s .. string.format("%q", o)
	elseif type(o) == "table" then
		s = s .. "{\n"
		local len = #o
		for k, v in pairs(o) do
			if(type(k) ~= "number" or (type(k) == "number" and k > len)) then
				s = s .. '  ' .. k .. ' = '
			end
			s = s .. serialize(v)
			s = s .. ",\n"
		end
		s = s .. "}"
	elseif type(o) == "boolean" then
		if o then
			s = s .. "true"
		else
			s = s .. "false"
		end
	else
		s = s .. " [" .. type(o) .. "]"
	end

	return s
end

function get_rows(sql)
	local rows = {}
	assert (dbh:query(sql, function(row)
		table.insert(rows, row)
	end))
	return rows
end

local rows = get_rows("select * from dialtasks where done = 0" .. " limit " .. config.limit)
debug(serialize(rows))

for i = 1, #rows do
	local row = rows[i]
	local status = json:execute({ command = "status", data = {} })
	if status.sessions.count.active >= config.maxchannels then break end
	if status.sessions.rate.current >= config.sps then break end

	local id = tonumber(row.id)
	local uuid = row.uuid
	local caller = row.caller
	local called = row.called
	local service = row.service -- 暂时不用

	if uuid == "" then
		uuid = api:execute("create_uuid")
		debug("uuid = " .. uuid)
	end

	local cmd = string.format("[origination_uuid=%s][origination_caller_id_number=%s]originate sofia/gateway/%s/%s &park", uuid, caller, called, config.gw)
	debug(cmd)
	-- api:execute(cmd)

	local sql = string.format("update dialtasks set done = 1, uuid = '%s' where id = %d", uuid, id)
	debug(sql)
	-- dbh:query(sql)
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值