C# Middle Man

Hi I recently began a new job and my first task was to develop a server to replace the TrixBox HUD Server. It is used as a middle man to relay messages to client software to notify our call center agents of incoming calls(screen pops), etc.

Apparently, our Asterisk box doesn’t like too many connections, so the HUD server is used for the one connection and then relays info to the clients.

But the HUD server has had intermittent losses of connections to Asterisk, etc.

I found an example C# manager piece that logs into the Asterisk server and listens for events. It catches and prints a large number of events and then just stops working. But it doesn’t say it’s been disconnected. A co-worker said he heard that Asterisk may drop the connection without notification. Is this true?

I’ll post the code below:

class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Console.WriteLine("Quick and Dirty Asterisk Manager Daemon Test:\n");

            // Connect to the asterisk server.
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.15.13"), 5038);
            clientSocket.Connect(serverEndPoint);

            // Login to the server; manager.conf needs to be setup with matching credentials.
            clientSocket.Send(Encoding.ASCII.GetBytes("Action: Login\r\nUsername: username\r\nSecret: password\r\nActionID: 1\r\n\r\n"));

            int bytesRead = 0;


            do
            {
                byte[] buffer = new byte[1024];
                bytesRead = clientSocket.Receive(buffer);

                //Console.WriteLine(bytesRead + " bytes from asterisk server.");

                string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);

                if (response != "")
                {
                    Console.WriteLine(response);
                }

                if (Regex.Match(response, "Message: Authentication accepted", RegexOptions.IgnoreCase).Success)
                {
                    // Send a ping request the asterisk server will send back a pong response.
                    clientSocket.Send(Encoding.ASCII.GetBytes("Action: Ping\r\nActionID: 2\r\n\r\n"));
                }
            } while (clientSocket.Connected == true) ; //while (bytesRead != 0);

            Console.WriteLine("Connection to server lost.");
            Console.ReadLine();
        } 
    }

Can anyone help? I’m a little out of my element having never worked with Asterisk. Thanks in advance for any help.

Eric Windham

Sorry guys

The page was sticking so I stopped and resubmitted twice, but the post went through anyways.

If any mods are watching, could you please delete the other two identical posts.

i have found that rather than having something log in to asterisk and listen for events, it is much more expeditious to program asterisk to fire off events and have your program sitting somewhere else to catch and process them. we are doing what you are attempting by simply firing events of on call pickup and call hangup. by keeping it at the channel level instead of at the global level, the burden on asterisk is much lighter and it does not depend on any lengthy logged in connections via the AMI which I have found seems to drag down the asterisk performance:

exten => s,1,Answer
exten => s,2,AGI(fireStartEvent)

exten => s,n,Hangup
exten => s,n,DeadAGI(fireFinishEvent) <=== optional for the more daring

if you want to make it even simpler and not use AGI, you could simply use CURL to fire off messages to a web service.

OK

I understand what you are saying, but I have no idea how to implement something like that. Does Asterisk have the ability already to do this, or is it something you have to implement?

Does this include running AGI scripts?

Look at AstManProxy, it does exactly what you need.

Yes the Asterisk Manager Interface does not like lots of connections and disconnects. The AstManProxy maintains one connection to AMI and accepts many connections from other sources. If the AMI connection drops for any reason AstManProxy will reconnect seamlessly. Its totally configurable on how you want it to reconnect.

http://www.voip-info.org/tiki-index.php?page=AstManProxy

thanks swaterhouse

Is there any documentation on AstManProxy? I went to the page you linked to and also took a look at the install and readme files in the svn trunk. All I can see is how to connect to the asterisk server. No info on how to connect to AstManProxy or how to retrieve information.

Can you have it send information to a client based on extension dialed or callerid?

I guess I’m asking how configurable it is and where is the documenation for configuring it?

there is documentation in the README file in the root folder and also in the doc folder of the download.

The C# example in my original post loses it’s connection to Asterisk server after a minute or so.

I wrote another piece with the asterisk-java package. It seems to stay connected longer due to the fact that the Manager class auto-reconnects. But eventually the connection is lost.

The whole reason for trying this was b/c the Hud Lite server from trixbox seemed to be losing it’s connection.

Has anyone else had problems with Asterisk dropping connections on the default port?

Hi

Well to be honest no I have sites with FOP monintoring multiple server with 100+ extensions and never loosing connection to either.

FOP uses a proxy to manage connections to AMI the same way as AstManProxy and is available seperately as simpleproxy.pl (look in the wiki for more info).

If you put any of the available proxy’s in front of your C# code you will not have the disconect issues.

We used the Asterisk.NET framework to build an operator panel and faced the same issues. As soon as we put AstManProxy in the middle the issue went away.

How does one log on to the astmanproxy as compared to just logging onto the AMI (using asterisk.net). I can log onto AMI directly just fine.

I installed Astmanproxy and it fixed my problems. We will now use Astman. instead of Hud Lite for our Agent client software to connect to.

dghundt,

you use the same login action as you would normally in the AMI. Astmanproxy intercepts certain actions and login is one of those. Make sure you are connecting to the right port for astmanproxy. It will be different than the AMI default port. You can set it in astmanproxy.conf

OK

So now we ready to go live with our new application with astmanproxy as our proxy. My problem now is I can’t get astmanproxy to run on startup. Our phone server reboots every morning before our call center opens and I need for astmanproxy to start when the the the server restarts.

I took the sample init.d file from the astmanproxy installation and edited the daemon variable to match the location of our astmanproxy executable. But it is still not starting on reboot. Any help would be great.

Thanks
Eric

here is my version of the init.d script

save this file as /etc/init.d/astmanproxy

#!/bin/bash
#
# yum           This shell script enables the automatic use of AstManProxy
#
# Author:       Scott Waterhouse
#
# chkconfig:    - 50 01
#
# description:  Enable use of AstManProxy
# processname:  astmanproxy
# config: /etc/asterisk/astmanproxy.conf
#

# source function library
. /etc/rc.d/init.d/functions



start() {
        echo -n "Starting AstManProxy: "

        #pid='pidof -x astmanproxy'
        #if [ "$pid_length" != "0" -a "$pid_length" == "" ]
        #        then
        #               /usr/local/sbin/astmanproxy
        #        fi

        pid=`pidof astmanproxy|awk '{print ($0)}'`
        if [ $pid > 0 ]
                then
                        echo -n " process already started! "
                else
                        /usr/local/sbin/astmanproxy
                fi

        pid_length=`pidof -x astmanproxy|awk '{print length($0)}'`
        if [ "$pid_length" == "0" -a "$pid_length" != "" ]
                then
                        failure
                else
                        success
                fi
        echo
}


stop() {
        echo -n "Stopping AstManProxy: "

        pid=`pidof astmanproxy|awk '{print ($0)}'`
        if [ $pid > 0 ]
                then
                        kill $pid
                        #echo $pid
                fi

        pid=`pidof astmanproxy|awk '{print ($0)}'`
        if [ $pid > 0 ]
                then
                        failure
                else
                        success
                fi

        echo
}

restart() {
        stop
        start
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart}"
        exit 1
esac

exit 0

set it to excutable

you also need to make sure its set to startup as well by doing a

Sorry it’s taken so long for me to reply. But that worked perfectly. Thanks alot.

I’ve got another problem now. I have a C# app that agents are using to connect to the astmanproxy instance to receive events from the pbx server.

It looks like some agents aren’t receiving all of the events. In particular, ones that pertain to them(by sip id or event uniqueID).

Is it possible that astmanproxy is losing some of the events? The largest number of agents connected at any given time is about 15 if that helps.

Thanks again for all your help.