亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩,日本久久久久,日本-区二区三区免费精品,中文字幕日本亚洲欧美不卡

 首頁(yè) > 新聞 > 專家觀點(diǎn) >

《FreeSWITCH: VoIP實(shí)戰(zhàn)》:執(zhí)行長(zhǎng)期運(yùn)行的嵌入式腳本Lua語(yǔ)言例子

2012-08-27 17:02:34   作者:杜金房    來(lái)源:FreeSWITCH    評(píng)論:0  點(diǎn)擊:


  眾所周知,F(xiàn)reeSWITCH中可以使用嵌入式的腳本語(yǔ)言javascript、lua等來(lái)控制呼叫流程。而更復(fù)雜一點(diǎn)操作可能就需要使用Event Socket了。其實(shí)不然,嵌入式的腳本也可以一直運(yùn)行,并可以監(jiān)聽所有的Event,就像使用Event Socket起一個(gè)單獨(dú)的Daemon一樣。

  這里我們以lua為例來(lái)講一下都有哪些限制以及如何解決。

  首先,在控制臺(tái)或fs_cli中執(zhí)行一個(gè)Lua腳本有兩種方式,lua和luarun。二者的不同就是lua是在當(dāng)前線程中運(yùn)行的,所以,它會(huì)阻塞;而luarun會(huì)spawn一個(gè)新的線程,不會(huì)阻塞當(dāng)前的線程執(zhí)行。

  另外,你也可以寫到lua.conf配置文件中,這樣它就能隨FreeSWITCH一起啟動(dòng)。

 <param name="startup-script" value="gateway_report.lua"/>

  腳本后面可以加參數(shù),如 luarun test.lua arg1 arg2,在腳本中,就可以通過(guò)argv[1], argv[2]來(lái)獲得參數(shù)的值。而argv[0]是腳本的名字。

  如果要讓腳本一直運(yùn)行,腳本中必須有一個(gè)無(wú)限循環(huán)。你可以這樣做:

while true do
  -- Sleep for 500 milliseconds
  freeswitch.msleep(500);
  freeswitch.consoleLog("info", "blah...");
end

  但這樣的腳本是無(wú)法終止的,由于FreeSWITCH使用swig支持這些嵌入式語(yǔ)言,而有些語(yǔ)言沒有退出機(jī)制,所以,所有語(yǔ)言的退出機(jī)制都沒有在FreeSWITCH中實(shí)現(xiàn),即使unload相關(guān)的語(yǔ)言模塊也不行,也是因?yàn)槿绱,為了避免產(chǎn)生問(wèn)題,所有語(yǔ)言模塊也都不能unload。

  另外,使用freeswitch.msleep() 也不安全,Wiki上說(shuō): Do not use this on a session-based script or bad things will happen。

  既然是長(zhǎng)期運(yùn)行的腳本,那,為什么為停止呢?是的,大部分時(shí)間你不需要,但,如果你想修改腳本,總不會(huì)每次都重啟FreeSWITCH吧?尤其是在調(diào)試的時(shí)候。

  那,還有別的辦法嗎?

  我們可以使用事件機(jī)制構(gòu)造另一個(gè)循環(huán):

con = freeswitch.EventConsumer("all");                                                                        
for e in (function() return con:pop(1) end) do
  freeswitch.consoleLog("info", "event\n" .. e:serialize("xml"));
end

  上面的代碼中,con被初始化成一個(gè)事件消費(fèi)者。它會(huì)一直阻塞并等待FreeSWITCH發(fā)出一個(gè)事件,并打印該事件的XML表示。當(dāng)然,事件總會(huì)有的。如每個(gè)電話初始化、掛機(jī)等都會(huì)有相應(yīng)的事件。除此之外,F(xiàn)reeSWITCH內(nèi)部也會(huì)毎20秒發(fā)出一個(gè)heartbeat事件,這樣你就可以定時(shí)執(zhí)行一些任務(wù)。

  當(dāng)然如果使用 con:pop(0)也可以變成無(wú)阻塞的,但你必須在循環(huán)內(nèi)部執(zhí)行一些sleep()以防止腳本占用太多的資源。

  通過(guò)這種方法,你應(yīng)該就能想到辦法讓腳本退出了。那就是,另外執(zhí)行一個(gè)腳本觸發(fā)一個(gè)custom的事件,當(dāng)該腳本監(jiān)測(cè)到特定的custom事件后退出。當(dāng)然你也可以不退出,比方說(shuō),打印一些信息以用于調(diào)試。

  我寫了一個(gè)gateway_report.lua腳本。就用了這種技術(shù)。思路是:監(jiān)聽所有事件。如果收到hangup,則判斷是通過(guò)哪個(gè)gateway出去的,并計(jì)算一些統(tǒng)計(jì)信息。如果需要保存這些信息,可以有以下幾種方式:

  1. fire_event,即觸發(fā)另一個(gè)事件,這樣,如果有其它程序監(jiān)聽,就可以收到這個(gè)事件,從而可以進(jìn)行處理,如存入數(shù)據(jù)庫(kù)等。
  2. http_post,發(fā)一個(gè)HTTP post請(qǐng)求到一個(gè)HTTP server,HTTP server接收到請(qǐng)求后進(jìn)行下一步處理。其中,http_post是無(wú)阻塞的,以提高效率,即只發(fā)請(qǐng)求,而不等待處理結(jié)果。
  3. db,可以通過(guò)luasql直接寫到數(shù)據(jù)庫(kù),未完全實(shí)現(xiàn)
  4. 當(dāng)然你也可以直接通過(guò)io.open寫到一個(gè)本地文件,未實(shí)現(xiàn)...

  由于這種腳本會(huì)在FreeSWITCH內(nèi)部執(zhí)行,需要消耗FreeSWITCH的資源,因此,在大話務(wù)量(確切來(lái)說(shuō)是“大事件量”)的情況下還是應(yīng)該用Event Socket。

相關(guān)熱詞搜索: FreeSWITCH VoIP

上一篇:呼叫中心建設(shè)常見專業(yè)名詞

下一篇:最后一頁(yè)

分享到: 收藏

專題

霍邱县| 略阳县| 临西县| 南丹县| 栾城县| 花莲市| 芜湖县| 牟定县| 晋州市| 胶南市| 新丰县| 元江| 兴宁市| 彰化市| 山西省| 库伦旗| 封丘县| 贵南县| 固安县| 永丰县| 铁岭县| 石城县| 唐海县| 宝清县| 丽水市| 长阳| 贵南县| 益阳市| 将乐县| 北川| 麻江县| 宁南县| 平阳县| 临潭县| 津市市| 环江| 卓资县| 明光市| 修武县| 安化县| 拉萨市|