James Knight James Knight - 1 year ago 91
Linux Question

Telnet socket gateway to Coldfusion Event Gateway to Connect to Asterisk AMI

I would like my ColdFusion app to be able to record events being streamed via telnet from an Asterisk host through the Management API. The ColdFusion Event gateway can listen to a particular port but cannot initiate a connection itself, so I need a gateway that can initiate a telnet connection to the Asterisk host (on a specified port) and push the streamed events to the ColdFusion server (on a specified port). I really don't want to reinvent the wheel so are there any utilities out that that can do this?

My terminology may not be correct as I'm not that technical but I hope I've explained the requirement enough! The 'utility' could reside on a Linux or windows platform.

To connect to and be authenticated by the Asterisk host telnet stream, the following must be sent:

Action: login<CRLF>
Username: usr<CRLF>
Secret: abc123<CRLF>

I am aware that a previous question was posted similar to this (but not answered), but I'm happy for a solution outside ColdFusion


Answer Source

If all you need to do is capture events from the Asterisk server, I would suggest a different approach.

As you seem to be using the Asterisk AMI, take a look Asterisk-Java. From what I have read, it is a java library that handles the low level socket communication and parsing for you and provides a higher level interface for interacting with an Asterisk server. So it is capable of initiating a connection, capturing events and a lot more.

In theory you could open a connection and register to receive events when the application starts. As long as the connection stays open, the application will receive events from Asterisk. When the application ends, just close the connection to halt the events.

Initialize Connection

To simply capture events, start by creating a connection to the Asterisk server. Just supply the proper host and credentials:

managerFactory = createObject("java", "org.asteriskjava.manager.ManagerConnectionFactory");
connection = managerFactory.init( hostNameOrIP
                                 , portNum
                                 , userName
                                 , theSecret ).createManagerConnection();

Registering for Events

In order to receive events, you must first register a ManagerEventListener with the connection. Normally that would require writing a custom java class that implements the proper interface. However, with a bit of dynamic proxy magic, you can use a standard CFC instead. Any events from Asterisk will be routed directly to the CFC and can be handled with CF code.

To add a listener, create a CFC with a single function named onManagerEvent. This function will be called whenever a registered event occurs on the Asterisk server.

// YourCFCListener.cfc
component {
    public void function onManagerEvent(any managerEvent)
        // For demo purposes, just output a summary of the event to a log file
        WriteLog( text=arguments.managerEvent.toString(), file="AsteriskListenerLog" );

Next create a proxy and register it with the connection.

cfcListener = new ManagerEventListener();
proxyListener = createDynamicProxy("path.YourCFCListener"
      , [ "org.asteriskjava.manager.ManagerEventListener"] );
connection.addEventListener( proxyListener );

Receiving Events:

To start receiving events, login and connect to the server. Use the mask to specify the events you want to receive: "off", "on" or a comma delimited list of specific events (ie "system,call,log").

// receive ALL events

Once the connection is open, you will see events written to the demo log file (assuming there is server activity). For a one time test, let the page sleep() for a few seconds to allow some events to flow. Then close the connection and stop the events:


In a real application, you would probably open the connection once and store it in a persistent scope, like application. Then close it only when the application shuts down.

Looking at the API, there is a LOT more you can do with it. However, the above should provide a basic POC example to get you started with capturing events.