一、 离线话单有三种保存方式:
1. 文件保存: 方便,快捷, 简配置, 支持多格式, 但是如果是多台集群的话, 取出话单比较麻烦要一台一台的取。
2. 数据库保存: 可以集中管理话单, 统计, 分析, 查询, 但是对第三方资源有依赖。
3. HTTP到远程服务保存: 更灵活, 可以支持更多业务及更复杂业务的操作, 可以做到实时监控, 但HTTP服务可靠性要求非常高(实际应用中我会选择这种方式)
二、 文件保存方式的配置及参数分析:
INSERT INTO cdr VALUES ("${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${en
d_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}");
"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duratio
n}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}"
"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}"
,"${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}","${read_codec}","${write_codec}","${sip_user_agent}","${call_clientcode}","${sip_rtp_rxstat}"
,"${sip_rtp_txstat}","${sofia_record_file}"
"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duratio
n}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${sip_user_agent}","${sip_p_rtp_stat}"
"${accountcode}","${caller_id_number}","${destination_number}","${context}","${caller_id}","${channel_name}","${bridge_channel}","${last_a
pp}","${last_arg}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${amaflags}","${uuid}","${userfield}"
"${uuid}","${signal_bond}","${direction}","${ani}","${destination_number}","${answer_stamp}","${end_stamp}","${billsec}","${accountcode
}","${userfield}","${network_addr}","${regex('${original_caller_id_name}'|^.)}","${sip_gateway_name}"
1. templates里定义了各种话单的样式模板, 如有sql:入库语句, example为文本的','号隔开的记录话单, 其它的也类似, 其中的字段为channel中的变量字段 , 在挂机后的最终值。
caller_id_name: 主叫方昵称;
caller_id_number:主叫号码;
destination_number:被叫号码;
content: 内容;
start_stamp: 开始时间;
anser_stamp: 应答时间;
end_stamp: 结束时间;
duration: 呼叫总时间, 开始到结束的总时间;
billsec: 计费总时长, 应答时间到结束时间总长;
hangup_cause:挂断原因
uuid:本leg唯一ID;
bleguuid: 另一方leg唯一ID;
accountcode: 帐号;
2. 让话单文件每5分钟或1000条 这样的条件产生一个对帐文件的做法有以下3种:
A: 用脚本操作: fs_cli -x "cdr_csv rotate" 定时5分钟或一千条时执行这个指令即可;
B: 0 * * * * fs_cli -x "cdr_csv rotate" 在linux上加入定时任务进行操作;
C: kill -HUP freeswitch进程ID; 这个不知道会不会对主业务有影响, 个人觉得前两种足以, 这个就不用了吧。
三、直接写入数据库: 这个方法只支持内嵌数据库, 不实用, 这里从略。
四、 使用HTTP服务器接收话单 (比较实用)
有三个模块可用, mod_xml_cdr, mod_json_cdr, mod_format_cdr 前两个分别是产生xml和json的话单, 最后一个可以配置产生xml或json格式的话单, 直接配置HTTP服务地址及认证方式, 再开发一套HTTP业务逻辑处理的应用服务用来对话单做各种处理。
一般配置如下项就差不多了:
//认证用户密码 //实际的发送地址 //错误及超时重试次数 //重试延迟时间 //日志本地保存目录 //错误日志目录 //url是否要base64编码
xml话单格式串类似如下:
CS_REPORTING
inbound
11
0=1;36=1;38=1;51=1
1=1;2=1;3=1
2e831835-d336-4735-b3e5-90e5d7dc8187
192.168.0.2
56866
192.168.0.2
56866
udp
1000
1000%40192.168.0.2
192.168.0.2
1000
BD37552C-4B5
...
1000
XML
1000
1000
1000
192.168.0.2
1000
1000
2e831835-d336-4735-b3e5-90e5d7dc8187
default
sofia/default/[email protected]
1274439432438053
1274439432448060
0
0
0
1274439438418776
0
0
[HttpPost]
public void CDR(string uuid)
{
var auth = ASCIIEncoding.ASCII.GetString(
Convert.FromBase64String(Request.Headers["AUTHORIZATION"]));
// TODO: Using auth check against your DB or whatever if user:pass is authorized.
// Get the xml from the input stream.
StreamReader r = new StreamReader(Request.InputStream);
string xml = r.ReadToEnd();
// Strips some unwanted chars.
xml.Substring(4, xml.Length - 4);
// Parse the string. Used XElement below but you could use XmlDocument also.
XElement elm = XElement.Parse(xml);
// Now using xpath or LINQ grab the element values you need.
// For ex: YOUR_ELEMENT could = variables/hangup_cause.
string selectedElm = Uri.UnescapeDataString(elm.XPathSelectElement("//" + "YOUR_ELEMENT").Vmialue);
}
完结!