Technical Helpweb

Dialogic® PowerMedia™ Extended Media Server (PowerMedia XMS) - more articles

XMS 2.2 RESTful demo for C# Part 2

Introduction

Following on from XMS RESTful demo for C# Part 1 this article describes a simple C# library "MCXMSLib" which contains some functions and objects that can be used to communicate with PowerMedia XMS 2.2 using the xmsrest.xsd (XML Schema Definition). Additionally, this article describes a simple console based application that uses the library and implements a sample call flow which will answer inbound calls, play a video and then hangup. This sample code can be used as a base to add additional functionality. 

Details  

The attached project, "MCSimpleXMSTest" is a Microsoft Visual Studio 2010 based solution containing two projects, "MCXMSLib" (the XMS library) and "MCSimpleXMSTest" (the sample application). Both of these projects have a reference to the external DLL "Syzygy.Common.dll" which is contained in the "External" directory and contains various useful C# classes including a logging object that is used in these projects.

MCXMSLib

This PowerMedia XMS library contains four main components:

[1] xmsrest.xsd / xmsrest.cs

This is the XML Schema Definition (XSD) and the C# classes generated from the XSD respectively. The generated C# definition file was modified to make sure everything is in the "MCantale.XMS.RESTapi" namespace but aside from that is left as generated by the "xsd.exe" tool.

[2] EventDispatcher.cs

The event dispatcher. This will set up an event handler with the PowerMedia XMS at startup (optionally removing any existing event handlers that may be left behind / orphaned) and process any inbound HTTP responses or requests from PowerMedia XMS.

[3] CallDispatcher.cs

The call dispatcher is called by the event dispatcher to determine which specific call object should receive the incoming message. It maintains a list of all calls that are in progress and is responsible for generating new calls (either in response to a make call request or incoming call request) and for hanging up and deleting them. Again, optionally it can detect and delete any calls that were in progress when the application is started.

[4] CallBase.cs

This is a class which represents a single call. It contains various functions to accept and answer calls and to do things such as play a file. It is an abstract base class and as such, the expectation is that the user of this library would derive the user's own class from this one to implement a specific call flow. By default, CallBase will do nothing apart from to delete the call resource in response to an incoming hangup request.

Additionally, there are a number of "helper" functions that are defined in "RestHelpers.cs". These implement the functions described in XMS RESTful demo for C# Part 1.

Finally, "RestSettings.cs" is a static class which contains the PowerMedia XMS server IP address, port and application ID that are used elsewhere in the library. These must be set by the application before the event dispatcher is invoked.

MCSimpleXMSTest

The sample application shows how to invoke the EventDispatcher class to start a simple call flow. By default, it will wait for inbound calls (depending on how many channels are licensed on the XMS server) and will answer them in audio+video mode and play a short video. The call will then hangup. The use is free to hangup at any time.

The program itself is contained within the "Program.cs" file, in which there is a class "MyCall" that implements a call flow which derives from the "CallBase" class.

  • When incoming call event is detected, the "AcceotCall()" function will be called.
  • When the call is ringing "AnswerCall()" which be called.
  • Upon the call being connected, "PlayFile()" is called to play a video/audio file.
  • Once the play has been completed, "Hangup()" is called to disconnect the call.

Note that the "OnEndPlay()" event handler is still called even if the play was terminated by the call hanging up.  There is a check for the termination reason to make sure that the application doesn't hangup twice.

   class MyCall : CallBase
   {
      protected override void OnConnected()
      {
         PlayFile("file://verification/video_clip_nascar.wav",
                  "file://verification/video_clip_nascar.vid");
      }

      protected override void OnEndPlay()
      {
         foreach (KeyValuePair<string, string> item in this._LastEventData)
         {
            if (item.Key.ToLower() == "reason" && item.Value.ToLower() == "hangup")
            {
               return;
            }
         }

         Hangup();
      }

      protected override void OnIncoming()
      {
         AcceptCall();
      }

      protected override void OnRinging()
      {
         if (this.Direction == "inbound")
         {
            AnswerCall();
         }
      }
   }

The main application first tells the logging object "LoggingSingleton.Instance" to log to both to a file and to the console.

      LoggingSingleton.Instance.LogToFile   = true;
      LoggingSingleton.Instance.LogToStdout = true;

It then sets the PowerMedia XMS IP address, port and application ID.   The user will need to modify these values with information that is appropriate for the environment where the sample application will be executed. 

      RestSettings.Instance.ServerIP    = "192.168.186.104";
      RestSettings.Instance.ServerPort = 81;
      RestSettings.Instance.AppID      = "app"; 

It then disconnects any existing event handlers. Note that this will actually remove any existing event handlers which use the application ID specified.

      EventDispatcher<MyCall>.DisconnectAllHandlers;

From there, a new call handler is created specifying that it should create call objects with the type "MyCall" and these call objects will then be instantiated:  

      EventDispatcher<MyCall> ev = new EventDispatcher<MyCall>() { DeleteAllCallsOnConnect = true; };
      ev.Start(); 

Now the application will spin around in a loop waiting for a key press to exit:

      while (!needExit)
      {
         ConsoleKeyInfo info = Console.ReadKey(true);

         switch (info.KeyChar)
         {
            case 'x':
            case 'X':
               needExit = true;
               break;
         }

         Thread.Sleep(10);
      }

Finally the event dispatcher is stopped which will asynchronously delete the event handler and dispose of it:

      ev.Stop();
      ev.WaitForStop();

      ev.Dispose();
      ev = null;

The program will create output to the console and also to the file "MCSimpleXMSTest-<DATETIME>.log" where <DATETIME> is a formatted date/time string:

Wed Oct 15 10:43:31.413 2014 | Library     | Debug2  | EventDispatcher::GetEventHandlers : Sent GET http://192.168.186.104:81/default/eventhandlers?appid=app
Wed Oct 15 10:43:31.441 2014 | Library     | Debug2  | EventDispatcher::GetEventHandlers : Received 200 OK
Wed Oct 15 10:43:31.442 2014 | Library     | Debug3  | EventDispatcher::GetEventHandlers : <web_service version="1.0">
Wed Oct 15 10:43:31.442 2014 | Library     | Debug3  | <eventhandlers_response size="0">
Wed Oct 15 10:43:31.442 2014 | Library     | Debug3  | </eventhandlers_response>
Wed Oct 15 10:43:31.442 2014 | Library     | Debug3  | </web_service>
Wed Oct 15 10:43:31.823 2014 | Library     | Info    | EventDispatcher::GetEventHandlers : Found 0 existing event handlers
Wed Oct 15 10:43:31.832 2014 | Library     | Debug2  | EventDispatcher::InternalRunThread : Entering InternalRunThread()
Wed Oct 15 10:43:31.832 2014 | Library     | Info    | EventDispatcher::InternalRunThread : Connecting to event handler...
Wed Oct 15 10:43:32.199 2014 | Library     | Debug2  | EventDispatcher::ConnectToEventHandler : Sent POST http://192.168.186.104:81/default/eventhandlers?appid=app
Wed Oct 15 10:43:32.230 2014 | Library     | Debug2  | EventDispatcher::ConnectToEventHandler : Received 201 Created
Wed Oct 15 10:43:32.246 2014 | Library     | Debug2  | EventDispatcher::ConnectToEventHandler : EventHandler URI is "http://192.168.186.104:81/default/eventhandlers/9d35496f-d3e7-4134-801b-2e4c02fda88b?appid=app", OID is "9d35496f-d3e7-4134-801b-2e4c02fda88b"
Wed Oct 15 10:43:32.247 2014 | Library     | Debug2  | EventDispatcher::ConnectToEventHandler : EventHandler connected
Wed Oct 15 10:43:32.255 2014 | Library     | Debug2  | XMLHelper::SendHttpRequest : Sent GET http://192.168.186.104:81/default/calls?appid=app
Wed Oct 15 10:43:32.257 2014 | Library     | Debug2  | XMLHelper::SendHttpRequest : Received 200 OK
Wed Oct 15 10:43:32.258 2014 | Library     | Debug1  | CallDispatcher::GetCalls : Received web service request :
Wed Oct 15 10:43:32.258 2014 | Library     | Debug1  | <web_service version="1.0">
Wed Oct 15 10:43:32.258 2014 | Library     | Debug1  | <calls_response size="0">
Wed Oct 15 10:43:32.258 2014 | Library     | Debug1  | </calls_response>
Wed Oct 15 10:43:32.258 2014 | Library     | Debug1  | </web_service>
Wed Oct 15 10:43:32.265 2014 | Library     | Info    | CallDispatcher::GetCalls : Found 0 RESTapi calls
Wed Oct 15 10:43:32.270 2014 | Library     | Debug2  | EventDispatcher::InternalProcessEventsThread : Entering InternalProcessEventsThread()
Wed Oct 15 10:43:32.271 2014 | Library     | Debug2  | EventDispatcher::InternalProcessEventsThread : Sent GET http://192.168.186.104:81/default/eventhandlers/9d35496f-d3e7-4134-801b-2e4c02fda88b?appid=app
Wed Oct 15 10:43:32.273 2014 | Library     | Debug2  | EventDispatcher::InternalProcessEventsThread : Received 200 OK
Wed Oct 15 10:43:32.273 2014 | Library     | Info    | EventDispatcher::InternalProcessEventsThread : Waiting for events...
Wed Oct 15 10:43:33.648 2014 | Library     | Debug2  | EventDispatcher::InternalStop : Interrupting InternalRunThread...
Wed Oct 15 10:43:33.648 2014 | Library     | Debug2  | EventDispatcher::InternalStop : Attempting to join InternalRunThread...
Wed Oct 15 10:43:33.649 2014 | Library     | Debug2  | EventDispatcher::InternalRunThread : Caught ThreadInterruptedException in InternalRunThread()!
Wed Oct 15 10:43:33.651 2014 | Library     | Info    | EventDispatcher::InternalRunThread : Disconnecting from event handler...
Wed Oct 15 10:43:33.654 2014 | Library     | Debug2  | EventDispatcher::DisconnectFromEventHandler : Sent DELETE http://192.168.186.104:81/default/eventhandlers/9d35496f-d3e7-4134-801b-2e4c02fda88b?appid=app
Wed Oct 15 10:43:33.656 2014 | Library     | Debug2  | EventDispatcher::InternalProcessEventsThread : Leaving InternalProcessEventsThread()
Wed Oct 15 10:43:33.657 2014 | Library     | Debug2  | EventDispatcher::DisconnectFromEventHandler : Received 204 No Content
Wed Oct 15 10:43:33.657 2014 | Library     | Debug2  | EventDispatcher::DisconnectFromEventHandler : EventHandler disconnected
Wed Oct 15 10:43:33.658 2014 | Library     | Debug2  | EventDispatcher::InternalRunThread : Leaving InternalRunThread()

The full demo can be downloaded here: MCSimpleXMSTest.zip.

Product List

Dialogic® PowerMedia™ XMS 2.2

 

Related Documentation

 XMS RESTful demo for C# Part 1

  


See also:
XMS 2.2 RESTful demo for C# Part 1


Feedback

Please rate the usefulness of this page:  
0 - not useful at all
1 - potentially useful
2 - quite useful
3 - very useful
4 - exactly the information I needed     

Please enter a comment about this page:

First published: 12-Dec-2014
Open access: Product rule: open; Page rule: Auto