通過FastAGI協議能夠用最簡單的方法使我們的JAVA應用程序和Asterisk交互。AGI腳本能夠處理任何呼入或通過Manager API發起的呼出。
AGI(Asterisk Gateway Interface)讓你可以向Asterisk的撥號計劃發送腳本,傳統的腳本和Asterisk之間的通訊是通過標準輸入和標準輸出,並且腳本必需和Asterisk運行在同一服務器上。
這此缺點已經由FastAGI解決,FastAGI基於AGI通過TCP/IP Socket連接替代標準輸入和標準輸出做爲溝通的媒介。
你可以使用FastAGI運行Java應用程序(可以在不同的機器上運行Asterisk) ,它僅啓動一次AGI 腳本直到它被關閉。使用此協議結合Java的多線程支持可以構建非常快的腳本。
Asterisk-Java提供了一個容器幫助你運行你的JAVA腳本,並接收Asterisk服務器連接的,解析請求或通過URL調用你的腳本。
Hello AGI!
寫AGI腳本你必需實現AgiScript的接口,你可以通過繼承實現了AgiScript接口的BaseAgiScript並覆蓋它的方法來進一步簡化這一工作。
一個簡單的AGI腳本的例子:
import org.asteriskjava.fastagi.AgiChannel;
import org.asteriskjava.fastagi.AgiException;
import org.asteriskjava.fastagi.AgiRequest;
import org.asteriskjava.fastagi.BaseAgiScript;
public class HelloAgiScript extends BaseAgiScript
{
public void service(AgiRequest request, AgiChannel channel)
throws AgiException
{
// Answer the channel...
answer();
// ...say hello...
streamFile("welcome");
// ...and hangup.
hangup();
}
}
編譯:
$ javac -cp asterisk-java.jar HelloAgiScript.java
$
下一步,在Asterisk撥號規則裏爲你的腳本添加一個呼叫。
你可能需要在extensions.conf默認的節裏添加一個分機1300:
[default]
...
exten => 1300,1,Agi(agi://localhost/hello.agi)
用運行Asterisk-Java機器的IP地址代替代碼中的“localhost”。
重新加載Asterisk確保更改生效。
現在你必須映射腳本的名稱hello.agi到我們剛剛創建的HelloAgiScript。默認情況下通過啓動AgiServer時調用classpath 路徑下的fastagi-mapping.properties屬性文件來完成。如:
hello.agi = HelloAgiScript
您的目錄現現在應包含以下文件:
$ ls -l
-rw-r--r-- 1 srt srt 163689 2005-03-11 22:07 asterisk-java.jar
-rw-r--r-- 1 srt srt 26 2005-03-11 20:50 fastagi-mapping.properties
-rw-r--r-- 1 srt srt 624 2005-03-11 22:07 HelloAgiScript.class
-rw-r--r-- 1 srt srt 438 2005-03-11 20:50 HelloAgiScript.java
最後我們運行 AgiServer:
$ java -jar asterisk-java.jar
如果是 Asterisk-Java 0.3.1 或更早的版本,你需要用
$ java -cp asterisk-java.jar:. org.asteriskjava.fastagi.DefaultAgiServer
在Windows平臺:
$ java -cp asterisk-java.jar;. org.asteriskjava.fastagi.DefaultAgiServer
如果你看到一些類似於如下的日誌輸出表示AgiServer已經成功開始運行:
Mar 11, 2005 10:20:12 PM org.asteriskjava.fastagi.DefaultAgiServer run
INFO: Thread pool started.
Mar 11, 2005 10:20:12 PM org.asteriskjava.fastagi.DefaultAgiServer run
INFO: Listening on *:4573.
When you call extension 1300 you will see the AGI script being launched:
Mar 11, 2005 10:22:47 PM org.asteriskjava.fastagi.DefaultAgiServer run
INFO: Received connection.
Mar 11, 2005 10:22:47 PM org.asteriskjava.fastagi.AgiConnectionHandler run
INFO: Begin AgiScript HelloAgiScript on AgiServer-TaskThread-0
Mar 11, 2005 10:22:48 PM org.asteriskjava.fastagi.AGIConnectionHandler run
INFO: End AgiScript HelloAgiScript on AgiServer-TaskThread-0
擴展範例
查看BaseAgiScript的文檔,你將發現更多的可以用在你的腳本中的方法。如你想用的方法不在BaseAgiScript中,或你想用你的命令擴展FastAGI,你可以用channel.sendCommand(AgiCommand)方法發送任意的命令。
使用AGI命令你可以通過URL傳遞參數給你的腳本,在AgiRequest中你可以通過調用getParameter(String)或getParameterValues(String)讀取這些參數。
如果你想傳遞名稱爲user,值爲john的參數給你的腳本hello.agi,你可以這樣寫:
exten => 1300,1,Agi(agi://localhost/hello.agi?user=john)
你可以傳遞多個參數,參數中的特殊字符必需爲URL編碼。
如果你要寫一個複雜的腳本,請注意您的AgiScript必須是線程安全的。只有一個實例被用來處理所有請求,這是一個類似於servlet容器的引擎。
配置
你可以通過設置兩個屬性來調整DefaultAgiServer:bindPort、poolSize;
bindPort爲設置TCP端口服務器偵聽端口。FastAGI默認端口爲4573,如果你修改了,在extensions.conf中請使用你設置的新端口。如你將bindPort屬性修改爲1234,在extensions.conf中設置如下:
exten => 1300,1,Agi(agi://localhost:1234/hello.agi)
DefaultAgiServer爲AgiScripts使用一個固定大小的線程池。poolSize確定有多少線程可以同時使用,因此,你應該將它設置爲AgiServer能夠處理的併發的數量。poolSize默認值爲10。
這些屬性配置可以通過classpath下的fastagi.properties的文件進行配置。
如下:
bindPort = 1234
poolSize = 20