Stephen Misel, Misel Consulting, LLC

NOTE: This article was originally posted in 2005 and is now somewhat outdated. Fortunately, everything contained herein should still work even with Asterisk 1.6.

What is FastAGI, and why would you want it?

Put simply, FastAGI gives Asterisk the ability to communicate with AGI applications over a socket. The FastAGI app can run anywhere and on any operating system. Mission-critical applications can be spread out amongst several servers and load-balanced for redundancy and scalability.

Resource-hungry AGI applications no longer need to run on the same machine as Asterisk.

FastAGI applications aren’t much more complex than regular AGI, and don’t take much longer to develop and test.

Let’s get our feet wet and look at a very simple Perl AGI application. It says “Welcome” and hangs up.

AGIDemo.pl

#!/usr/bin/perl -w -T
#  AGIDemo.pl - Demonstration of AGI.
#  Stephen A. Misel
#  http://www.miselconsulting.com/
#

use Asterisk::AGI;
$|=1;
my $AGI = new Asterisk::AGI;
$AGI->setcallback(\&mycallback);
my  %input = $AGI->ReadParse();
sleep(1);
$AGI->stream_file("welcome","*");
sleep(1);
exit;

sub mycallback {
  my ($returncode) = @_;
  &log("CALLBACK");
  &cleanup;
  print STDERR "User Disconnected ($returncode)\n";
  exit($returncode);
}

This program implements the same functionality, but uses FastAGI.

FastAGIDemo.pl

#!/usr/bin/perl -w -T
#
#  FastAGIDemo.pl - Demonstration of FastAGI.
#  Stephen A. Misel
#  http://www.miselconsulting.com/
#

package FastAGIDemo;

use Net::Server;
use Asterisk::AGI;
@ISA = qw(Net::Server);

sub process_request {
  use vars qw(%input $AGI);
  STDIN->autoflush(1);
  $AGI = new Asterisk::AGI;
  $AGI->setcallback(\&mycallback);
  %input = $AGI->ReadParse();
  sleep(1);
  $AGI->stream_file("welcome","*");
  sleep(1);
}

sub mycallback {
  my ($returncode) = @_;
  &log("CALLBACK");
  &cleanup;
  print STDERR "User Disconnected ($returncode)\n";
  exit($returncode);
}

FastAGIDemo->run(port=>4577, user=>'nobody', group=>'nobody', background=>1);
exit;

In order to use the first example, you’ll need the Asterisk::AGI Perl module. Asterisk::AGI and Net::Server are needed for the FastAGI demonstration.

To use the regular AGI demo, save the AGIDemo.pl program in your agi-bin directory and make sure it is executable. In your extensions.conf, add the following and reload Asterisk.

exten => 109,1,agi(AGIDemo.pl)

.. where 109 is an available extension.

For the FastAGI demo, save the FastAGIDemo.pl program anywhere on your Asterisk machine. Make sure it’s executable and run it:

# ./FastAGIDemo.pl
Process Backgrounded
2005/01/03-07:26:20 FastAGIDemo (type Net::Server) starting! pid(14865)
Binding to TCP port 4577 on host *
Setting gid to "99 99"
Setting uid to "99"
#

In order to test the FastAGIDemo, we need to tell your asterisk machine to connect to the local AGI socket:

exten => 108,1,agi(agi://127.0.0.1:4577)

You should be able to run these applications by simply dialing 108 or 109.

Advanced Topics

With some simple tweaks, it’s possible to:

  • Run the FastAGIDemo on a separate machine and have Asterisk execute it over the network.
  • Pre-fork FastAGIDemo applications, so they are always ready and willing to serve FastAGI requests.
  • Use FastAGIDemo as a framework for future FastAGI projects.