?
概述
freeswitch是一款簡單好用的VOIP開源軟交換平臺。
mod_xml_curl模塊支持從web服務獲取xml配置,本文介紹如何動態(tài)獲取dialplan配置。
環(huán)境
centos:CentOS? release 7.0 (Final)或以上版本
freeswitch:v1.6.20
GCC:4.8.5
dialplan查找流程
我們在“switch_xml_parse_file”函數(shù)中設置一個斷點,并打印堆棧。
Breakpoint 1, switch_xml_parse_file (file=file@entry=0x7fdda1a015f0 "/tmp/34096cac-311f-11ee-b31e-672fb2a27310.tmp.xml") at src/switch_xml.c:1625
1625?????????????????????????? if ((xml = switch_xml_parse_fd(fd))) {
(gdb) bt
#0? switch_xml_parse_file (file=file@entry=0x7fdda1a015f0 "/tmp/34096cac-311f-11ee-b31e-672fb2a27310.tmp.xml") at src/switch_xml.c:1625
#1? 0x00007fddee4d5258 in xml_url_fetch (section=<optimized out>, tag_name=<optimized out>, key_name=<optimized out>, key_value=<optimized out>, params=0x7fdd68004d10, user_data=0x1ad1ae8) at mod_xml_curl.c:311
#2? 0x00007fddf71e0ec0 in switch_xml_locate (section=section@entry=0x7fddae9fc7e8 "dialplan", tag_name=tag_name@entry=0x0, key_name=key_name@entry=0x0, key_value=key_value@entry=0x0, root=root@entry=0x7fdda1a01b00,
??? node=node@entry=0x7fdda1a01af8, params=0x7fdd68004d10, clone=clone@entry=SWITCH_FALSE) at src/switch_xml.c:1675
#3? 0x00007fddae9fc214 in dialplan_xml_locate (node=0x7fdda1a01af8, root=0x7fdda1a01b00, caller_profile=0x7fddd004d690, session=0x7fddd0030328) at mod_dialplan_xml.c:613
#4? dialplan_hunt (session=0x7fddd0030328, arg=<optimized out>, caller_profile=0x7fddd004d690) at mod_dialplan_xml.c:658
#5? 0x00007fddf71342ef in switch_core_standard_on_routing (session=0x7fddd0030328) at src/switch_core_state_machine.c:281
#6? switch_core_session_run (session=0x7fddd0030328) at src/switch_core_state_machine.c:643
#7? 0x00007fddf712c9fe in switch_core_session_thread (thread=<optimized out>, obj=0x7fddd0030328) at src/switch_core_session.c:1648
#8? 0x00007fddf71286f3 in switch_core_session_thread_pool_worker (thread=0x7fddd004f5e0, obj=<optimized out>) at src/switch_core_session.c:1711
#9? 0x00007fddf7213e10 in dummy_worker (opaque=0x7fddd004f5e0) at threadproc/unix/thread.c:151
#10 0x00007fddf4a11ea5 in start_thread () from /lib64/libpthread.so.0
#11 0x00007fddf4065b0d in clone () from /lib64/libc.so.6
(gdb)
從堆棧中可以看出,一通呼叫查找動態(tài)dialplan的流程如下。
switch_core_session_thread
switch_core_session_run
switch_core_standard_on_routing
dialplan_hunt
dialplan_xml_locate
switch_xml_locate
xml_url_fetch
switch_xml_parse_file
web服務
mod_xml_curl模塊依賴于web服務,需要自己創(chuàng)建一個web接口并動態(tài)的返回xml配置。
下面是python3.10實現(xiàn)的一個簡單的web服務接口函數(shù),從基類“BaseHTTPRequestHandler”繼承并實現(xiàn)簡單的返回邏輯。
??? def fsDialplan(self):
??????? length = int(self.headers['content-length'])?
??????? datas = self.rfile.read(length)
??????? logging.info('/fs/dialplan request, data=%s' % urllib.parse.unquote(datas))
??????? respcode = '''<document type="freeswitch/xml">
<section name="dialplan" description="dialplan-url">
??? <include>
??????? <context name="public">
??????????? <extension name="test-url" continue="false">
??????????????? <condition field="destination_number" expression="^(\d+)$">
????????????????? ??<action application="answer"/>
??????????????????? <action application="playback" data="/usr/local/freeswitch/sounds/dialplan-test-url.wav"/>
??????????????? </condition>
??????????? </extension>
??????? </context>
??? </include>
</section>
</document>
'''
??????? self.send_response(200)
??????? self.send_header('Content-Type', 'application;charset=utf-8')
??????? self.end_headers()
??????? self.wfile.write(respcode.encode('utf-8'))
??????? return
web服務響應消息格式注意事項,必須有“section”段,xml格式不能使用壓縮格式,否則會解析錯誤。
配置
檢查conf/autoload_configs/modules.conf.xml文件,mod_xml_curl模塊要放在配置的頂部。
<load module="mod_console"/>
<load module="mod_logfile"/>
<load module="mod_xml_curl"/>
修改conf/autoload_configs/xml_curl.conf.xml文件。
<configuration name="xml_curl.conf" description="cURL XML Gateway">
? <bindings>
??? <binding name="dialplan">
????? <param name="gateway-url" value="http://10.55.55.137:8080/fs/dialplan" bindings="dialplan"/>
??? </binding>
? </bindings>
</configuration>
測試
使用10011發(fā)起呼叫,日志如下。
2023-08-03 11:08:27.438976 [INFO] mod_dialplan_xml.c:637 Processing 10011 <10011>->13712345678 in context public
2023-08-03 11:08:27.478976 [CONSOLE] mod_xml_curl.c:323 XML response is in /tmp/042fcd1e-31ab-11ee-b34d-672fb2a27310.tmp.xml
Dialplan: sofia/external/10011@10.55.55.138 parsing [public->test-url] continue=false
Dialplan: sofia/external/10011@10.55.55.138 Regex (PASS) [test-url] destination_number(13712345678) =~ /^(\d+)$/ break=on-false
Dialplan: sofia/external/10011@10.55.55.138 Action answer()
Dialplan: sofia/external/10011@10.55.55.138 Action playback(/usr/local/freeswitch/sounds/dialplan-test-url.wav)
呼叫結果符合預期。
問題
網(wǎng)友的問題:當使用 dialplan時,這個動態(tài)獲取的dialplan優(yōu)先級最高,每通電話都會執(zhí)行到這個dialplan。 而有些電話我不想走xml動態(tài)獲取的,就想走本地配置的,這個問題怎解決呢?
方案1,mod_xml_curl模塊內(nèi)部已實現(xiàn)的邏輯,當web服務返回“NOT FOUND”時,自動走本地配置。缺點是對web服務依賴,每通呼叫都會到web服務查詢。
方案2,修改“switch_xml_locate”函數(shù),增加條件控制,比如caller是“123456”時直接使用本地配置。缺點是不夠靈活,配置條件修改較困難。
方案3,修改mod_xml_curl模塊的“xml_url_fetch”函數(shù),對web響應的xml結果進行緩存,設置過期時間,減少了對web服務的依賴,又有動態(tài)配置的優(yōu)點。缺點是web配置的生效會增加緩存的延遲,弱一致性。
以上方案僅僅從測試結果推導,并未真正實現(xiàn),實現(xiàn)細節(jié)有不確定性。
總結
mod_xml_curl模塊動態(tài)獲取dialplan數(shù)據(jù),控制呼叫流程。
未解決問題。
如何更靈活的控制從web服務和本地xml文件獲取配置。
如何緩存web服務的xml配置。
如何解決web服務不可用的時候,呼叫流程問題。
空空如常文章來源:http://www.zghlxwxcb.cn/news/detail-631939.html
求真得真文章來源地址http://www.zghlxwxcb.cn/news/detail-631939.html
到了這里,關于freeswitch的mod_xml_curl模塊動態(tài)獲取dialplan的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!