Asterisk-Java 教程(中文版) --FastAGI协议

FastAGI协议

通过FastAGI协议能够用最简单的方法使我们的JAVA应用程序和Asterisk交互。AGI脚本能够处理任何呼入或通过Manager API发起的呼出。

这此缺点已经由FastAGI解决,FastAGI基于AGI通过TCP/IP Socket连接替代标准输入和标准输出做为沟通的媒介。

你可以使用FastAGI运行Java应用程序(可以在不同的机器上运行Asterisk) ,它仅启动一次AGI 脚本直到它被关闭。使用此协议结合Java的多线程支持可以构建非常快的脚本。

Asterisk-Java提供了一个容器帮助你运行你的JAVA脚本,并接收Asterisk服务器连接的,解析请求或通过URL调用你的脚本。

写AGI脚本你必需实现AgiScript的接口,你可以通过继承实现了AgiScript接口的BaseAgiScript并覆盖它的方法来进一步简化这一工作。

查看BaseAgiScript的文档,你将发现更多的可以用在你的脚本中的方法。如你想用的方法不在BaseAgiScript中,或你想用你的命令扩展FastAGI,你可以用channel.sendCommand(AgiCommand)方法发送任意的命令。

FastAGI协议

通过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;

importorg.asteriskjava.fastagi.AgiException;

import org.asteriskjava.fastagi.AgiRequest;

import org.asteriskjava.fastagi.BaseAgiScript;

public class HelloAgiScript extendsBaseAgiScript

{

public void service(AgiRequest request,AgiChannel channel)

throws AgiException

{

// Answer the channel...

answer();

// ...say hello...

streamFile("welcome");

// ...and hangup.

hangup();

}

}

编译:

$ javac -cp asterisk-java.jarHelloAgiScript.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:07asterisk-java.jar

-rw-r--r-- 1 srt srt 26 2005-03-11 20:50fastagi-mapping.properties

-rw-r--r-- 1 srt srt 624 2005-03-11 22:07HelloAgiScript.class

-rw-r--r-- 1 srt srt 438 2005-03-11 20:50HelloAgiScript.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 PMorg.asteriskjava.fastagi.DefaultAgiServer run

INFO: Thread pool started.

Mar 11, 2005 10:20:12 PMorg.asteriskjava.fastagi.DefaultAgiServer run

INFO: Listening on *:4573.

When you call extension 1300 you will seethe AGI script being launched:

Mar 11, 2005 10:22:47 PMorg.asteriskjava.fastagi.DefaultAgiServer run

INFO: Received connection.

Mar 11, 2005 10:22:47 PMorg.asteriskjava.fastagi.AgiConnectionHandler run

INFO: Begin AgiScript HelloAgiScript onAgiServer-TaskThread-0

Mar 11, 2005 10:22:48 PMorg.asteriskjava.fastagi.AGIConnectionHandler run

INFO: End AgiScript HelloAgiScript onAgiServer-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

时间: 2024-12-11 22:40:54

Asterisk-Java 教程(中文版) --FastAGI协议的相关文章

学java教程之普通方法重载

学编程吧学java教程之普通方法重载发布了,欢迎通过xuebiancheng8.com来访问 先来看什么是普通方法重载呢,先来看一个例子 public class Person{ String username; int age; public void hello(){ System.out.println("Hello"); } public void hello(String username){ System.out.println("你好"+usernam

学java教程之对象数组

学编程吧学java教程之对象数组发布了,欢迎通过xuebiancheng8.com来访问 什么是对象数组呢,对象数组顾名思义是对象的数组. 首先定义一个对象 public class Student{ private String username; private String password; setter,getter.... } 如上面所示,定义了一个Student对象 加入现在需要3个Student对象怎么办呢,我们得 Student stu1 = new Student(); St

java教程(五)SSH框架-配置

前言:从这篇博客开始我将继续讲述Java教程:SSH篇,主要内容围绕SSH框架分析与搭建,今天先简单介绍一下SSH的配置. SSH配置顺序是: spring-->hibernate-->struts 1. 建立web-project ,并添加Spring支持,添加JAR包时注意,aop  core web commons等包要加载,然后一直下一步就可以成功添加spring支持: 2. 添加hibernate支持,同样注意包的选择, 下一步中注意,选择添加到spring中(spring conf

学java教程之集合框架

学编程吧学编程学IT教程之java教程集合框架发布了,欢迎通过xuebiancheng8.com来访问 java中的集合框架故名思议就是针对集合的框架.那什么是集合呢,前面已经学习过数组,没错,数组就是一组数据的集合,换句话说数组也是一种特殊的集合框架,可以完成集合的功能.那数组在使用的时候有没有不方便的地方呢,比方说数组有可能有满的时候,满了怎么办,我们是不是得自己写程序来更改数组的大小呢,而且还要把原来的数组赋值到新的数组的原来位置上,这样很明显数组用起来不是特别方便,很多功能得让我们自己去

学java教程之封装

学编程吧学java教程之封装发布了,欢迎大家通过xuebiancheng8.com来访问 下面来分析面向对象中的封装,什么是封装呢.先来段代码 public class Person{ String username; int age; } Person p = new Person(); p.username="张三"; p.age=-10; 上面实例化了一个Person对象p,然后赋值,这里我们将年龄的值赋值成了-10,这里很明显是不正确的,因为年龄不能为负的,那怎么办呢,这里我们

学java教程之面向对象(四)

学编程吧学java教程之面向对象(四)发布了,欢迎通过xuebiancheng8.com来访问 本次课来分析java面向对象之构造方法.什么是构造方法呢,构造方法听名字顾名思义,构造的时候执行的方法就叫构造方法. 没错,构造方法就是在构造对象的时候执行的方法,就是构造方法,那什么时候构造对象呢,是不是在new的时候调用构造对象呢,所以构造方法就是在new对象的时候执行的方法就是构造方法.构造方法一般用来为对象赋初值.完成对象的初始化. 下面我们来看如何定义构造方法. public class P

java教程

http://www.xfonlineclass.com/ http://java.itcast.cn/ http://www.xasxt.com/index.php/list/161 [UI]http://www.xueui.cn/ java教程,布布扣,bubuko.com

学java教程之访问权限

学编程吧学java教程之访问权限控制发布了.欢迎大家通过xuebiancheng8.com来访问 java中在使用封装的时候有四种访问权限控制符. public 在任意包的任意类中都可以访问任何方法和属性 protected 在同包或者任意子类中可以访问任意方法和属性 默认控制符 也就是什么访问符都不用,在同包中可以访问 private 在同一类中可以访问属性和方法 以上这几个叫访问控制符,他们的权限从大到小.这几个关键词在java中自始至终都用用到.定要牢记. 更多内容请通过xuebianch

学java教程之面向对象(三)

学编程吧学java教程之面向对象发布了,欢迎通过xuebiancheng8.com来访问 上面两次分析了类和对象,以及如何定义对象.下面来分析下如何使用对象 下面先定义一个类 public class Car{//定义类名单词首字母要大写,同时见明知意 String name; //定义了属性名字 int price;    //定义了价格 public void run(){   //定义了run方法 System.out.println("汽车在跑"); } public void