Programmable Voice

  1. Home
  2. Docs
  3. Programmable Voice
  4. FAQ
  5. What is the preferred way to handle Hangup Events?

What is the preferred way to handle Hangup Events?

Often, you will want to transfer callers to an operator, or place a user into a conference. In these cases, you will want to wait for the user to hangup before you disconnect them and dispose of their associated Telephony Resources. For this reason, we’ve created the Disconnect Event, so that you are notified when there is a hangup.

Here is a code example that shows how to use it:

public class Disconnect
{
    public ChannelResource ChannelResource
    {
        get;
        set;
    }
 
    public VoiceResource VoiceResource
    {
        get;
        set;
    }
 
    public TelephonyServer TelephonyServer
    {
        get;
        set;
    }
 
    public Log Log
    {
        get;
        set;
    }
 
    public string DeviceName
    {
        get;
        set;
    }
 
 
    public Disconnect(ChannelResource channelResource, TelephonyServer telephonyServer, Log log)
    {
        ChannelResource = channelResource;
        DeviceName = ChannelResource.DeviceName;
        VoiceResource = channelResource.VoiceResource;
        TelephonyServer = telephonyServer;
        Log = log;
    }
 
    public string PhoneNumber
    {
        get;
        set;
    }
 
    public ChannelResource OutboundChannelResource
    {
        get;
        set;
    }
 
    public System.Threading.ManualResetEvent HangupEvent = new System.Threading.ManualResetEvent(false);
 
    public void RunScript()
    {
        try
        {
            // This assumes that someone is on the line and we would like to dial out
 
            // Register the hangup event to the inbound channel
            // The hangup event will trigger the ManualResetEvent HangupEvent so that the "WaitOne" below will return once this line disconnects
            ChannelResource.Disconnected +=new VoiceElements.Client.Disconnected(ChannelResource_Disconnected);
 
            // Get a Channel to dial out on.
            OutboundChannelResource = TelephonyServer.GetChannel();
 
            // Subscribe the OutboundChannel to the Disconnected event. By subscribing both to the same event, when either side disconnects, it will cause the "WaitOne" below to return
            OutboundChannelResource.Disconnected +=new VoiceElements.Client.Disconnected(ChannelResource_Disconnected);
 
            // We route the two channels together...When we do this before dialing, the inbound channel, should be able to hear ringing.
            OutboundChannelResource.RouteFull(ChannelResource);
 
            // Dial
            OutboundChannelResource.Dial(PhoneNumber);
 
            // Once the call connects, the person on the inbound channel resource should be able to speak with the person on the outbound channel resource
            // We can then wait until we disconnect, before the finally block get's executed.
 
            // When called with no parameters it will wait indefinitely, until "Set" is called on the Reset Event
            HangupEvent.WaitOne();
 
            // Alternatively, you can pass in a timeout period (perhaps 60 minutes)
            //HangupEvent.WaitOne(3600000);
        }
        catch (HangupException hex)
        {
            Log.WriteWithId(DeviceName, "Caller Hungup!");
        }
        catch (Exception ex)
        {
            Log.WriteException(ex, "Unexpected exception: {0}", DeviceName);
        }
        finally
        {
            // Make sure you unsubscribe from your events
            try
            {
                ChannelResource.Disconnected -= new VoiceElements.Client.Disconnected(ChannelResource_Disconnected);
            }
            catch{}
 
            if(OutboundChannelResource != null)
             {
                 try
                 {
                     OutboundChannelResource.Disconnect();
                 }
                 catch { }
 
                 try
                 {
                     ChannelResource.Disconnected -= new VoiceElements.Client.Disconnected(ChannelResource_Disconnected);
                 }
                 catch{}
 
                 try
                 {
                     OutboundChannelResource.Dispose();
                 }
                 catch { }
                 }
             }
 
               try
               {
                   ChannelResource.Disconnect();
               }
               catch { }
 
               try
               {
                   ChannelResource.Dispose();
               }
               catch { }
               }
 
            try
            {
                ChannelResource.Disconnect();
            }
            catch { }
 
            try
            {
                ChannelResource.Dispose();
            }
            catch { }
        }
    }
 
    void ChannelResource_Disconnected(object sender, VoiceElements.Client.DisconnectedEventArgs e)
    {
        Log.Write("Received Disconnect!"); 
        HangupEvent.Set();
    }
}

 

A Few Notes About the Sample Code Above:

Auto Reset Events and Manual Reset Events are very handy for synchronizing threads. We always want to make sure that the ChannelResources gets disconnected and disposed, so we always put those in the finally block.

We call WaitOne once the two calls are connected — this waits until a separate thread calls “Set” on the ManualResetEvent.

When a call disconnects, Voice Elements fires an event on a separate thread, and as you can see, it calls Set, thereby causing the WaitOne method to return. Once this happens, the code in the finally block will be executed, and cleanup the call (Disconnecting both channels, and disposing them).

If you have any questions about how to use the HangupEvent, don’t hesitate to contact support@inventivelabs.com.

Was this article helpful to you? Yes 14 No

How can we help?