當(dāng)1999年第一次創(chuàng)建Asterisk的時(shí)候,當(dāng)初的設(shè)計(jì)想法是針對(duì)獨(dú)立的Private Branch eXchange (PBX),它可以通過static.conf 文件來實(shí)現(xiàn)控制。呼叫控制是通過extensions.conf文件來實(shí)現(xiàn),我們稱之為撥號(hào)規(guī)則。
撥號(hào)規(guī)則的腳本通知Asterisk來執(zhí)行呼叫流程中的應(yīng)用程序。這種模式工作了很久時(shí)間。當(dāng)然,隨著技術(shù)的不斷演進(jìn),現(xiàn)在的功能比以前更加靈活,同時(shí)也支持了更多的功能模塊。
這些撥號(hào)規(guī)則的很多應(yīng)用是由C語言開發(fā),它們可以直接和Asterisk進(jìn)行通信交換。這些應(yīng)用可以訪問通道,媒體,橋和endpoints和其他的對(duì)象,通過這些對(duì)象來實(shí)現(xiàn)電話通信。
關(guān)于 AMI 和 AGI
Asterisk項(xiàng)目創(chuàng)建不久, 兩個(gè)應(yīng)用程序接口就已經(jīng)支持了Asterisk:Asterisk Gateway Interface (AGI) 和 Asterisk Manager Interface (AMI)。這兩種接口是為了實(shí)現(xiàn)不同的目的:- AGI 和Apache中的CGI類似。AGI 提供了Asterisk撥號(hào)規(guī)則和外部程序通信的接口,它可以用來操作撥號(hào)規(guī)則中的通道。一般情況下,這個(gè)接口是同步的,從AGI程序中發(fā)起的對(duì)通道進(jìn)行操作,流程完成后才能返回結(jié)果。
- AMI 則提供了一種在撥號(hào)規(guī)則中控制通道的機(jī)制。不像AGI,AMI 是異步的,是一種事件驅(qū)動(dòng)的接口。大部分情況下,AMI 不負(fù)責(zé)控制通道執(zhí)行-它提供通道狀態(tài)信息,也提供在什么地方發(fā)起通道執(zhí)行。
兩個(gè)接口都非常強(qiáng)大,提供了多種集成度可能性。使用AGI的話,可以開啟遠(yuǎn)端撥號(hào)規(guī)則的執(zhí)行,這樣就可以允許開發(fā)人員使用不同的程序語言PHP,Python,Java和其他的語言來集成Asterisk。使用AMI的話,可以顯示Asterisk狀態(tài),發(fā)起的呼叫和被控制的通道地址。如果同時(shí)使用兩種接口的話,可以把Asterisk當(dāng)成是一種引擎來開發(fā)其他的應(yīng)用。
但是使用這兩個(gè)接口來開發(fā)自定義的通信應(yīng)用程序時(shí),這兩種接口仍然存在一些缺點(diǎn):
- AGI 是同步的方式來工作的,當(dāng)對(duì)通道進(jìn)行處理時(shí),它會(huì)阻塞線程服務(wù)的AGI。當(dāng)開發(fā)人員創(chuàng)建一個(gè)新的通信程序時(shí),用戶經(jīng)常會(huì)需要獲得通道的響應(yīng)(DTMF事件,通道狀態(tài),等等);所以AGI操作就會(huì)變得非常困難,如果配合AMI來進(jìn)行操作的話,對(duì)開發(fā)人員是一個(gè)非常大的挑戰(zhàn)。
- 撥號(hào)規(guī)則可能是一個(gè)局限。無論是使用 AMI 或者 AGI,用戶的基本操作會(huì)限定在通道執(zhí)行中。如果需要更加強(qiáng)大的功能支持,很多基本的APIs接口功能都不能獲得很好的支持,例如這些APIs: bridges,endpoints,device state,message waiting indications,和通道中的實(shí)際媒體流處理。如果想通過AMI 和AGI來控制它們的話會(huì)變得非常困難,通常需要引入非常復(fù)雜的撥號(hào)規(guī)則控制流程來達(dá)到這些目的。
最后,兩種接口AMI和AGI都是Asterisk項(xiàng)目的早期接口,他們具有一定的生命周期。盡管這兩種接口非常強(qiáng)大,但是今天使用的技術(shù)中已不在是非常主要的手段。一些技術(shù)概念,例如SOAP, XML/JSON-RPC和REST也使用的不是非常多。因此需要一種原生態(tài)的,能夠快速適應(yīng)新技術(shù)開發(fā)Asterisk的技術(shù)來支持最新的技術(shù)發(fā)展潮流。
在Asterisk 12之前,如果用戶需要開發(fā)一套自定義的通信程序的話,用戶需要:
- 使用C語言開發(fā)一個(gè)Asterisk模塊,或者
- 自己使用AGI或者AMI寫一個(gè)自定義的程序來實(shí)現(xiàn),可能有時(shí)需要兩種接口同時(shí)使用來實(shí)現(xiàn)一個(gè)功能或使用一些小技巧修改撥號(hào)規(guī)則來實(shí)現(xiàn)這個(gè)功能。
ARI: 支持通信應(yīng)用開發(fā)的接口
Asterisk RESTful Interface (ARI) 的出現(xiàn)就是為了解決用戶的這些擔(dān)心的。AMI的優(yōu)勢(shì)在于對(duì)呼叫的控制,AGI 的優(yōu)勢(shì)是通過外部程序來執(zhí)行撥號(hào)規(guī)則的應(yīng)用程序,它們都不是為開發(fā)人員設(shè)計(jì)支持開發(fā)人員創(chuàng)建自己的通信應(yīng)用程序。ARI是一種異步工作方式,可以支持開發(fā)人員通過訪問Asterisk中的原始對(duì)象實(shí)體來開發(fā)自己的通信應(yīng)用程序,ARI可以通過REST接口訪問,例如channels,bridges,endpoints和 media等等原始數(shù)據(jù)。對(duì)象實(shí)體的控制則通過WebSocket來訪問JSON 事件來實(shí)現(xiàn)。
- ARI 不是通知通道執(zhí)行VoiceMail撥號(hào)規(guī)則的application或在撥號(hào)規(guī)則中轉(zhuǎn)發(fā)一個(gè)通道到VoiceMail。
- ARI可以支持用戶創(chuàng)建一個(gè)自己的VoiceMail 應(yīng)用程序。
- ARI 基礎(chǔ)
- ARI 由3個(gè)部分組成。它們是:
- 一個(gè) RESTful 接口支持終端來控制Asterisk的資源。
- 一個(gè)WebSocket,它在JSON中傳輸Asterisk資源到終端。
Stasis 撥號(hào)規(guī)則的應(yīng)用模塊,它來處理從Asterisk通道到終端的控制。
通過以上3個(gè)部分的結(jié)合,開發(fā)人員就可以實(shí)現(xiàn)對(duì)Asterisk基礎(chǔ)資源的控制,實(shí)現(xiàn)自定義通信應(yīng)用的開發(fā)。
什么是REST?
Representational State Transfer (REST) 是一種軟件架構(gòu),它具有以下幾個(gè)方面的特點(diǎn):
- 通信方式是通過client-server 模式進(jìn)行的。
- 通信是stateless的方式。服務(wù)器端不保存請(qǐng)求中的客戶端狀態(tài)。
- 連接分層,支持中間層實(shí)現(xiàn)路由和均衡負(fù)載。
- 非正式接口。請(qǐng)求中的資源和消息可以自己定義描述。
ARI 沒有嚴(yán)格限定在一個(gè)REST API。Asterisk作為一個(gè)獨(dú)立的應(yīng)用,它同樣建議狀態(tài)信息,可以通過ARI修改。例如,SIP電話可能掛機(jī),Asterisk就會(huì)對(duì)通道執(zhí)行掛機(jī)命令,盡管終端通過ARI沒有通知Asterisk對(duì)此SIP話機(jī)掛機(jī)。Asterisk以異步,state-ful 的工作方式工作:因此,ARI是RESTful。
什么是WebSocket?
WebSockets 是一種相對(duì)比較新的協(xié)議標(biāo)準(zhǔn)(RFC 6455),它可以支持客戶端和服務(wù)器端的雙向通信。此協(xié)議標(biāo)準(zhǔn)的主要目的是對(duì)基于瀏覽器的應(yīng)用提供一種支持雙向通信機(jī)制,不依賴于HTTP長(zhǎng)時(shí)間的服務(wù)器查詢或者其他非標(biāo)準(zhǔn)的機(jī)制。連接是用來傳遞從Asterisk到客戶端的異步事件。這些事件是和RESTful 接口相關(guān),但是它在技術(shù)上是獨(dú)立的。Asterisk可以通知客戶端本身的狀態(tài)修改,在原來狀態(tài)下,因?yàn)榭蛻舳嘶旌鲜褂昧薃RI。
什么是Stasis?
Stasis 是Asterisk撥號(hào)規(guī)則中的一個(gè)應(yīng)用模塊。它的機(jī)制是Asterisk 使用這個(gè)應(yīng)用模塊在撥號(hào)規(guī)則中實(shí)現(xiàn)通道控制。通常來說,ARI 應(yīng)用程序在Stasis 撥號(hào)規(guī)則中控制通道和Asterisk的其他資源。不在Stasis 撥號(hào)規(guī)則中的通道不能被ARI來控制,總體來說,ARI的目的是用戶創(chuàng)建自己的撥號(hào)規(guī)則應(yīng)用程序,不是來控制當(dāng)前存在的程序。
進(jìn)一步了解
這里多個(gè)頁面文檔介紹ARI和一些舉例。正常情況下,我們假設(shè):
- 用戶已經(jīng)注冊(cè)了一些SIP電話終端,可能使用chan_pjsip 或者 chan_sip。
- 用戶已經(jīng)對(duì)Asterisk有一定的基本了解。
- 對(duì)Python,JavaScript或者其他的高級(jí)開發(fā)語言有一定的了解。
大部分的經(jīng)歷不是直接創(chuàng)建HTTP REST 的結(jié)構(gòu),目前已經(jīng)有很多開發(fā)包封裝了這些接口。
獲得有價(jià)值的技術(shù)分享:請(qǐng)?jiān)L問www.freesip.org 技術(shù)論壇,關(guān)注公眾號(hào):asterisk-cn