中文字幕无码久久精品,13—14同岁无码A片,99热门精品一区二区三区无码,菠萝菠萝蜜在线观看视频高清1

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

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

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


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

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

  首先,在控制臺(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,在腳本中,就可以通過argv[1], argv[2]來獲得參數(shù)的值。而argv[0]是腳本的名字。

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

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

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

  另外,使用freeswitch.msleep() 也不安全,Wiki上說: 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)也可以變成無阻塞的,但你必須在循環(huán)內(nèi)部執(zhí)行一些sleep()以防止腳本占用太多的資源。

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

  我寫了一個(gè)gateway_report.lua腳本。就用了這種技術(shù)。思路是:監(jiān)聽所有事件。如果收到hangup,則判斷是通過哪個(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是無阻塞的,以提高效率,即只發(fā)請(qǐng)求,而不等待處理結(jié)果。
  3. db,可以通過luasql直接寫到數(shù)據(jù)庫(kù),未完全實(shí)現(xiàn)
  4. 當(dāng)然你也可以直接通過io.open寫到一個(gè)本地文件,未實(shí)現(xiàn)...

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

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

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

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

分享到: 收藏

專題