Exemplo n.º 1
0
        } /* PlayFile() */

        /// <summary>
        /// This is an example of how to populate and call a more complicated
        /// RESTapi structure. We play an audio/video file from here...
        /// </summary>
        /// <param name="audioUri"></param>
        /// <param name="videoUri"></param>
        ///
        protected virtual void PlayFile(String audioUri, RESTapi.audio_type_option audioType = RESTapi.audio_type_option.audioxwav, String videoUri = "", RESTapi.video_type_option videoType = RESTapi.video_type_option.videoxvid)
        {
            bool hasAudio = !String.IsNullOrWhiteSpace(audioUri);
            bool hasVideo = !String.IsNullOrWhiteSpace(videoUri);

            RESTapi.web_service ws = new RESTapi.web_service()
            {
                Item = new RESTapi.call()
                {
                    call_action = new RESTapi.call_action()
                    {
                        Item = new RESTapi.play()
                        {
                            offset      = "0s",
                            repeat      = "0",
                            delay       = "0s",
                            play_source = new RESTapi.play_source()
                            {
                                audio_uri           = hasAudio ? audioUri : String.Empty,
                                audio_type          = audioType,
                                audio_typeSpecified = hasAudio,
                                video_uri           = hasVideo ? videoUri : String.Empty,
                                video_type          = videoType,
                                video_typeSpecified = hasVideo,
                            }
                        }
                    }
                }
            };

            if (hasAudio)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "Call::PlayFile : Playing audio \"{0}\"...", audioUri);
            }

            if (hasVideo)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "Call::PlayFile : Playing video \"{0}\"...", videoUri);
            }

            String responseString = String.Empty;

            if (RestHelpers.SendHttpRequest(out responseString, CallURI, "PUT", ws))
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "Call::PlayFile : Play file OK");
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, responseString);
            }
            else
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error, "Call::PlayFile : Play file failed!");
                PutEvent(RESTapi.event_type.end_play);
            }
        } /* PlayFile() */
Exemplo n.º 2
0
        protected virtual void AnswerCall(RESTapi.media_type MediaType = RESTapi.media_type.audiovideo, bool AsyncCompletion = true)
        {
            /// <call answer="yes" media="audiovideo" signaling="yes" dtmf_mode="rfc2833" async_completion="yes"
            ///       async_dtmf="yes" async_tone="yes" rx_delta="+0dB" tx_delta="+0dB" cpa="no" info_ack_mode="automatic"/>
            ///

            RESTapi.web_service ws = new RESTapi.web_service()
            {
                Item = new RESTapi.call()
                {
                    answer                    = RESTapi.boolean_type.yes,
                    answerSpecified           = true,
                    async_completion          = AsyncCompletion ? RESTapi.boolean_type.yes : RESTapi.boolean_type.no,
                    async_completionSpecified = true,
                    media                  = MediaType,
                    mediaSpecified         = true,
                    dtmf_mode              = RESTapi.dtmf_mode_option.rfc2833,
                    async_dtmf             = RESTapi.boolean_type.yes,
                    async_dtmfSpecified    = true,
                    async_tone             = RESTapi.boolean_type.yes,
                    async_toneSpecified    = true,
                    info_ack_mode          = RESTapi.ack_mode_option.automatic,
                    info_ack_modeSpecified = true,
                }
            };

            String responseString = String.Empty;

            if (RestHelpers.SendHttpRequest(out responseString, CallURI, "PUT", ws))
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "Call::AnswerCall : AnswerCall OK");
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, responseString);

                // Note: If we use async_completion, we DON'T have to put the event
                // manually as it will (or rather... should) appear as a separate
                // event from the XMS server...
                //
                if (!AsyncCompletion)
                {
                    PutEvent(RESTapi.event_type.answered);
                }
            }
            else
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error, "Call::AnswerCall : AnswerCall failed!");
                Hangup();
            }
        }
Exemplo n.º 3
0
        } /* DeleteCall() */

        public void Hangup(string ResourceID)
        {
            String requestUri = String.Format("http://{0}:{1}/default/calls/{2}?appid={3}",
                                              RestSettings.Instance.ServerIP,
                                              RestSettings.Instance.ServerPort,
                                              ResourceID,
                                              RestSettings.Instance.AppID);

            T currentCall = GetCallByResourceID(ResourceID);

            if (currentCall != null)
            {
                RESTapi.web_service ws = new RESTapi.web_service()
                {
                    Item = new RESTapi.call()
                    {
                        call_action = new RESTapi.call_action()
                        {
                            Item = new RESTapi.hangup()
                            {
                                content_type = "text/plain",
                                content      = "data",
                            }
                        }
                    }
                };

                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "CallDispatcher::Hangup : Hanging up call with ID \"{0}\"...", ResourceID);

                String responseString = String.Empty;

                /// Send the hangup request...
                ///
                if (RestHelpers.SendHttpRequest(out responseString, requestUri, "PUT", ws))
                {
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "CallDispatcher::Hangup : Hangup OK");
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, responseString);
                }
                else
                {
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error, "CallDispatcher::Hangup : Hangup failed!");
                }

                /// Remember to delete the call resource...
                ///
                DeleteCall(ResourceID);
            }
        } /* Hangup() */
Exemplo n.º 4
0
        private void PutEvent(RESTapi.event_type type)
        {
            RESTapi.web_service ws = new RESTapi.web_service()
            {
                Item = new RESTapi.@event()
                {
                    type          = type,
                    resource_type = ResourceType,
                    resource_id   = ResourceID,
                }
            };

            /// IMPORTANT: Call the dispatcher IN A NEW THREAD or stuff will just
            /// randomly lock up / fail for no apparent reason!
            ///
            ThreadPool.QueueUserWorkItem(x => { this.Dispatcher.ProcessRequest(ws); });
        } /* PutEvent() */
Exemplo n.º 5
0
        protected virtual void AcceptCall(bool EarlyMedia = true, RESTapi.media_type MediaType = RESTapi.media_type.audiovideo)
        {
            /// <call accept="yes" early_media="yes" media="audiovideo" signaling="yes" dtmf_mode="rfc2833"
            ///       async_dtmf="yes" async_tone="yes" rx_delta="+0dB" tx_delta="+0dB" cpa="no" info_ack_mode="automatic"/>
            ///
            RESTapi.web_service ws = new RESTapi.web_service()
            {
                Item = new RESTapi.call()
                {
                    accept               = RESTapi.boolean_type.yes,
                    acceptSpecified      = true,
                    early_media          = EarlyMedia ? RESTapi.boolean_type.yes : RESTapi.boolean_type.no,
                    early_mediaSpecified = true,
                    media                  = MediaType,
                    mediaSpecified         = true,
                    dtmf_mode              = RESTapi.dtmf_mode_option.rfc2833,
                    async_dtmf             = RESTapi.boolean_type.yes,
                    async_dtmfSpecified    = true,
                    async_tone             = RESTapi.boolean_type.yes,
                    async_toneSpecified    = true,
                    info_ack_mode          = RESTapi.ack_mode_option.automatic,
                    info_ack_modeSpecified = true,
                }
            };

            String responseString = String.Empty;

            if (RestHelpers.SendHttpRequest(out responseString, CallURI, "PUT", ws))
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, "Call::AcceptCall : Accept call OK");
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1, responseString);

                PutEvent(RESTapi.event_type.ringing);
            }
            else
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error, "Call::AcceptCall : Accept call failed!");
                Hangup();
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Ok - if we get here (!) then we have a valid event associated with a
        /// specific call. We should handle the event (obviously!) appropriately.
        /// </summary>
        /// <param name="ws">The web_service request to process</param>
        ///
        protected virtual void HandleEvent(RESTapi.web_service ws)
        {
            RESTapi.@event @event = ws.Item as RESTapi.@event;

            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Event,
                                              "Call::HandleEvent : Processing event \"{0}\"",
                                              @event.type.ToString());

            this._LastEvent     = ws.Item as RESTapi.@event;
            this._LastEventData = null;

            if (this._LastEvent.event_data != null)
            {
                this._LastEventData = this._LastEvent.event_data.ToDictionary(x => x.name, x => x.value);

                /*string _Buf = "";
                 *
                 * foreach (KeyValuePair<string, string> kv in this._LastEventData)
                 * {
                 * _Buf += string.Format("  => {0}->{1}\n", kv.Key, kv.Value);
                 * }
                 *
                 * Logger.LogMessage("Call::HandleEvent : Event has associated event data:\n{0}", _Buf);*/
            }

            switch (@event.type)
            {
            case RESTapi.event_type.incoming:
                this.CallState = CallStateType.Ringing;
                OnIncoming();
                break;

            case RESTapi.event_type.ringing:
                this.CallState = CallStateType.Ringing;
                OnRinging();
                break;

            case RESTapi.event_type.accepted:
                this.CallState = CallStateType.Ringing;
                OnAccepted();
                break;

            case RESTapi.event_type.answered:
            case RESTapi.event_type.connected:
                this.CallState = CallStateType.Connected;
                OnConnected();
                break;

            case RESTapi.event_type.alarm:
                OnAlarm();
                break;

            case RESTapi.event_type.dtmf:
                OnDtmf();
                break;

            case RESTapi.event_type.end_play:
                OnEndPlay();
                break;

            case RESTapi.event_type.hangup:
                this.CallState = CallStateType.Hangup;
                OnHangup();
                break;

            default:
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error,
                                                  "Call::HandleEvent : Unhandled event \"{0}\"",
                                                  @event.type.ToString());
                break;
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// We received a web_service object to process... this function will
        /// determine if the request is for a new call or an existing call.
        /// Additionally, if the request is a hangup, we should delete the call
        /// from our list.
        /// </summary>
        /// <param name="ws"> The web_service request to process</param>
        ///
        public void ProcessRequest(RESTapi.web_service ws)
        {
            T currentCall = null;

            RESTapi.@event @event = ws.Item as RESTapi.@event;

            if (@event.type == RESTapi.event_type.keepalive)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1,
                                                  "CallDispatcher::ProcessRequest : Keepalive received");
                return;
            }

            String response = RestHelpers.RESTapiToXML(ws, typeof(RESTapi.web_service));

            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1,
                                              "CallDispatcher::ProcessRequest : Received web service request :\n{0}",
                                              response);

            if (@event.type == RESTapi.event_type.incoming)
            {
                /// Note that we probably should check that this is not an existing
                /// call / resource id rather than assuming...
                ///
                currentCall = new T()
                {
                    Dispatcher   = this as ICallDispatcher <CallBase>,
                    Direction    = "inbound",
                    ResourceID   = @event.resource_id,
                    ResourceType = @event.resource_type,
                    CallState    = CallBase.CallStateType.Ringing,
                };

                foreach (RESTapi.event_data data in @event.event_data)
                {
                    switch (data.name.ToLower())
                    {
                    case "caller_uri": currentCall.CallerUri = data.value; break;

                    case "called_uri": currentCall.CalledUri = data.value; break;

                    case "uri":        currentCall.Uri = data.value; break;

                    case "name":       currentCall.Name = data.value; break;
                    }
                }
            }
            else
            {
                foreach (T call in Calls)
                {
                    if (call.ResourceID == @event.resource_id)
                    {
                        currentCall = call;
                        break;
                    }
                }
            }

            if (currentCall != null)
            {
                /// The following is a way of calling a protected / private member
                /// of a class - kind of like using "friend class" in C++. It uses
                /// reflection.
                ///
                MethodInfo handleEventMethod = currentCall.GetType().GetMethod("HandleEvent", BindingFlags.Instance | BindingFlags.NonPublic);

                switch (@event.type)
                {
                case RESTapi.event_type.incoming:
                    Calls.Add(currentCall);
                    handleEventMethod.Invoke(currentCall, new object[] { ws });
                    break;

                case RESTapi.event_type.hangup:
                    handleEventMethod.Invoke(currentCall, new object[] { ws });
                    Calls.Remove(currentCall);
                    break;

                default:
                    handleEventMethod.Invoke(currentCall, new object[] { ws });
                    break;
                }
            }
        } /* ProcessRequest() */
Exemplo n.º 8
0
        } /* ProcessRequest() */

        /// <summary>
        /// Gets a list of any calls that are already in progress on the XMS server. We can
        /// use this to populate our calls list and potentially do "stuff" with them...
        /// </summary>
        ///
        public void GetCalls()
        {
            String uri = String.Format("http://{0}:{1}/default/calls?appid={2}",
                                       RestSettings.Instance.ServerIP,
                                       RestSettings.Instance.ServerPort,
                                       RestSettings.Instance.AppID);

            String responseString = String.Empty;

            if (RestHelpers.SendHttpRequest(out responseString, uri, "GET"))
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1,
                                                  "CallDispatcher::GetCalls : Received web service request :\n{0}",
                                                  responseString);

                RESTapi.web_service    ws        = (RESTapi.web_service)RestHelpers.XMLToRESTapi(responseString, typeof(RESTapi.web_service));
                RESTapi.calls_response Responses = (RESTapi.calls_response)ws.Item;

                int numCalls = 0;

                if (!int.TryParse(Responses.size, out numCalls))
                {
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error,
                                                      "CallDispatcher::GetCalls : Oops... RESTapi.calls_response.size is not a number!");
                    return;
                }

                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Info,
                                                  "CallDispatcher::GetCalls : Found {0} RESTapi calls",
                                                  numCalls);

                if (numCalls > 0 && Responses.call_response != null)
                {
                    /// Each "call_response" object corresponds to a single call in progress.
                    ///
                    foreach (RESTapi.call_response Response in Responses.call_response)
                    {
                        bool Exists = false;

                        foreach (T call in Calls)
                        {
                            if (call.ResourceID == Response.identifier)
                            {
                                Exists = true;
                                break;
                            }
                        }

                        if (!Exists)
                        {
                            this.Calls.Add(new T()
                            {
                                Dispatcher = this as ICallDispatcher <CallBase>,
                                ResourceID = Response.identifier,
                                CalledUri  = Response.destination_uri,
                                CallerUri  = Response.source_uri,
                                Direction  = Response.call_type.ToString(),
                                Uri        = Response.destination_uri,
                                Name       = Response.appid,
                                CallState  = Response.connected == RESTapi.boolean_type.yes ? CallBase.CallStateType.Connected : CallBase.CallStateType.Unknown,
                            });
                        }
                    }
                }
            }
        } /* GetCalls() */
Exemplo n.º 9
0
        } /* DisconnectFromEventHandler() */

        static public EventDispatcherList <T> GetEventHandlers()
        {
            EventDispatcherList <T> retval = new EventDispatcherList <T>();

            String uri = String.Format("http://{0}:{1}/default/eventhandlers?appid={2}",
                                       RestSettings.Instance.ServerIP,
                                       RestSettings.Instance.ServerPort,
                                       RestSettings.Instance.AppID);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

            request.Method          = "GET";
            request.ProtocolVersion = HttpVersion.Version11;

            try
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                  "EventDispatcher::GetEventHandlers : Sent GET {0}", uri);

                /// This waits for a response from the far end...
                ///
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
                    {
                        /// Read the result from the far end...
                        ///
                        String result = stream.ReadToEnd();

                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                          "EventDispatcher::GetEventHandlers : Received {0:D} {1}",
                                                          response.StatusCode, response.StatusDescription);

                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug3,
                                                          "EventDispatcher::GetEventHandlers : {0}", result);

                        RESTapi.web_service evresponse = RestHelpers.XMLToRESTapi(result, typeof(RESTapi.web_service)) as RESTapi.web_service;

                        if (evresponse != null)
                        {
                            /// We know that the actual object type is "eventhandlers_response"
                            /// in this case so we go ahead and cast it...
                            ///
                            RESTapi.eventhandlers_response evhandlers = evresponse.Item as RESTapi.eventhandlers_response;

                            if (evhandlers != null)
                            {
                                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Info,
                                                                  "EventDispatcher::GetEventHandlers : Found {0} existing event handlers",
                                                                  evhandlers.size);

                                if (evhandlers.eventhandler_response != null)
                                {
                                    foreach (RESTapi.eventhandler_response ev in evhandlers.eventhandler_response)
                                    {
                                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug3,
                                                                          "EventDispatcher::GetEventHandlers : Event handler :\n" +
                                                                          "  => identifier = {0}\n" +
                                                                          "  => href       = {1}\n" +
                                                                          "  => appid      = {2}\n",
                                                                          ev.identifier,
                                                                          ev.href,
                                                                          ev.appid);

                                        retval.Add(new EventDispatcher <T>()
                                        {
                                            _OID             = ev.identifier,
                                            _EventHandlerURI = ev.href.Contains("http://") ? String.Format("{0}?appid={1}", ev.href, ev.appid) : String.Format("http://{0}:{1}{2}?appid={3}", RestSettings.Instance.ServerIP, RestSettings.Instance.ServerPort, ev.href, ev.appid),
                                            _ConnectionState = ConnectionStateEnum.Connected,
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    HttpWebResponse response = ex.Response as HttpWebResponse;

                    if (response != null)
                    {
                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                          "EventDispatcher::GetEventHandlers : Received HTTP failure response {0} {1}",
                                                          (int)response.StatusCode, response.StatusDescription);
                    }
                }
                else
                {
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                      "EventDispatcher::GetEventHandlers : {0}\n{1}",
                                                      ex.Message.ToString(), ex.StackTrace.ToString());
                }

                return(retval);
            }
            catch (Exception ex)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                  "EventDispatcher::GetEventHandlers : {0}\n{1}",
                                                  ex.Message.ToString(), ex.StackTrace.ToString());
                return(retval);
            }

            return(retval);
        } /* GetEventHandlers() */
Exemplo n.º 10
0
        /// <summary>
        /// Connect to the XMS server's event handler. This demonstrates how to
        /// use the web service API that was generated from the XSD.
        /// </summary>
        /// <returns>true = success, false = failure</returns>
        ///
        private bool ConnectToEventHandler()
        {
            /// This is the URI we are sending the request to...
            ///
            String uri = String.Format("http://{0}:{1}/default/eventhandlers?appid={2}",
                                       RestSettings.Instance.ServerIP,
                                       RestSettings.Instance.ServerPort,
                                       RestSettings.Instance.AppID);

            /// Here we create the actual HTTP request. We set the method to one
            /// of "POST" or "GET". Note that we do have to  explicitly set the
            /// protocol version as XMS doesn't like the .NET default...
            ///
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

            request.Method          = "POST";
            request.ProtocolVersion = HttpVersion.Version11;

            /// This creates a RESTapi.web_service object which is the actual
            /// payload of the request... in this case, it's an event subscribe
            /// type request.
            ///
            RESTapi.web_service service = new RESTapi.web_service()
            {
                Item = new RESTapi.eventhandler()
                {
                    eventsubscribe = new RESTapi.eventsubscribe[]
                    {
                        new RESTapi.eventsubscribe()
                    }
                }
            };

            /// The RestHelpers class contains various functions for converting
            /// between RESTapi objects and XML / text. In this case, we need to
            /// convert from RESTapi -> an XML string.
            ///
            String requestContent = RestHelpers.RESTapiToXML(service, typeof(RESTapi.web_service));

            if (String.IsNullOrWhiteSpace(requestContent))
            {
                /// The conversion failed as the string is empty...
                ///
                return(false);
            }

            /// Set the content type and length appropriately...
            ///
            request.ContentType   = "application/xml";
            request.ContentLength = requestContent.Length;

            try
            {
                /// The following code sends the request. The "using" makes sure
                /// that if the request fails, the stream gets closed properly (ie.
                /// it cleans up stream exceptions correctly!)
                ///
                using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
                {
                    stream.Write(requestContent);
                    stream.Close();
                }

                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                  "EventDispatcher::ConnectToEventHandler : Sent POST {0}", uri);

                /// This waits for the response from the XMS server...
                ///
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
                    {
                        String result = stream.ReadToEnd();

                        if (String.IsNullOrWhiteSpace(result))
                        {
                            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                              "EventDispatcher::ConnectToEventHandler : POST response contained no payload!");
                            return(false);
                        }

                        /// If all went well and fingers (and toes) crossed, we have
                        /// a "payload" (ie. XML...) from the XMS server which contains
                        /// "stuff" for us to do things with...
                        ///
                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                          "EventDispatcher::ConnectToEventHandler : Received {0:D} {1}",
                                                          response.StatusCode, response.StatusDescription);

                        try
                        {
                            /// We first convert the XML/text response into a
                            /// web_service object...
                            ///
                            RESTapi.web_service evresponse = RestHelpers.XMLToRESTapi(result, typeof(RESTapi.web_service)) as RESTapi.web_service;

                            if (evresponse != null)
                            {
                                /// We know that the actual object type is "eventhandler_response"
                                /// in this case so we go ahead and cast it...
                                ///
                                RESTapi.eventhandler_response item = evresponse.Item as RESTapi.eventhandler_response;

                                /// We need to store the OID and EventHandler URI for later
                                /// use (ie. when we disconnect / process events!)
                                ///
                                this._OID             = item.identifier;
                                this._EventHandlerURI = String.Format("{0}?appid={1}", item.href, RestSettings.Instance.AppID);

                                if (!this._EventHandlerURI.Contains("http://"))
                                {
                                    this._EventHandlerURI = String.Format("http://{0}:{1}{2}?appid={3}",
                                                                          RestSettings.Instance.ServerIP, RestSettings.Instance.ServerPort, item.href, RestSettings.Instance.AppID);
                                }

                                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                                  "EventDispatcher::ConnectToEventHandler : EventHandler URI is \"{0}\", OID is \"{1}\"",
                                                                  this._EventHandlerURI, this._OID);
                            }
                        }
                        catch (Exception ex)
                        {
                            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                              "EventDispatcher::ConnectToEventHandler : {0}\n{1}",
                                                              ex.Message, ex.StackTrace);
                            return(false);
                        }

                        if (String.IsNullOrWhiteSpace(this._EventHandlerURI))
                        {
                            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                              "EventDispatcher::ConnectToEventHandler : EventHandler URI was null!");
                            return(false);
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                /// Process any exceptions that we caught above...
                ///
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    HttpWebResponse response = ex.Response as HttpWebResponse;

                    if (response != null)
                    {
                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                          "EventDispatcher::ConnectToEventHandler : Received HTTP failure response {0} {1}",
                                                          (int)response.StatusCode, response.StatusDescription);
                    }
                }
                else
                {
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                      "EventDispatcher::ConnectToEventHandler : {0}\n{1}",
                                                      ex.Message.ToString(), ex.StackTrace.ToString());
                }

                return(false);
            }
            catch (Exception ex)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                  "EventDispatcher::ConnectToEventHandler : {0}\n{1}",
                                                  ex.Message.ToString(), ex.StackTrace.ToString());
                return(false);
            }

            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                              "EventDispatcher::ConnectToEventHandler : EventHandler connected");
            return(true);
        } /* ConnectToEventHandler() */
Exemplo n.º 11
0
        /// <summary>
        /// This thread processes any events that occur whilst the connection to
        /// the XMS server is open. It sends a single "GET" request which then
        /// receives "chunks" of data. Ie. there is ONE request but MULTIPLE
        /// responses. We pass each of these "chunks" to the call dispatcher to
        /// work out what to do with them.
        /// </summary>
        ///
        public void InternalProcessEventsThread()
        {
            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                              "EventDispatcher::InternalProcessEventsThread : Entering InternalProcessEventsThread()");

            String ServerUri = String.Format("http://{0}:{1}",
                                             RestSettings.Instance.ServerIP,
                                             RestSettings.Instance.ServerPort);

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this._EventHandlerURI);
                request.Accept          = null;
                request.ContentType     = null;
                request.KeepAlive       = true;
                request.Method          = "GET";
                request.ProtocolVersion = HttpVersion.Version11;

                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                  "EventDispatcher::InternalProcessEventsThread : Sent GET {0}",
                                                  this._EventHandlerURI);

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
                    {
                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                          "EventDispatcher::InternalProcessEventsThread : Received {0:D} {1}",
                                                          response.StatusCode, response.StatusDescription);

                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Info,
                                                          "EventDispatcher::InternalProcessEventsThread : Waiting for events...");

                        while (!stream.EndOfStream)
                        {
                            String line = stream.ReadLine();

                            if (String.IsNullOrWhiteSpace(line))
                            {
                                continue;
                            }

                            int bufferLength = Int32.Parse(line, NumberStyles.AllowHexSpecifier);

                            if (bufferLength > 0)
                            {
                                /// MC : Thu Feb 19 10:52:00 GMT 2015
                                ///
                                /// Note that there was a pretty serious bug / omission in the following section whereby I had assumed that
                                /// stream.Read(...) would always return the whole data chunk. This is not the case. Sometimes (seemingly
                                /// when the data spans two TCP packets) stream.Read(...) returns LESS than "bufferLength" chars and we are
                                /// required to keep calling the function until we have ALL of the data. Failure to do this will cause an
                                /// exception when attempting to cast the data to a RESTapi.web_service object.
                                ///
                                char[] buffer     = new char[bufferLength + 1];
                                int    readLength = 0;
                                int    count      = 0;

                                while (readLength < bufferLength)
                                {
                                    readLength += stream.Read(buffer, readLength, bufferLength - readLength);
                                    count++;
                                }

                                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                                                  "EventDispatcher::InternalProcessEventsThread : Read {0} bytes from stream [{1} read{2}]",
                                                                  readLength, count, count == 1 ? "" : "s");

                                /// Cast the data to a web service event...
                                ///
                                RESTapi.web_service ws = RestHelpers.XMLToRESTapi(new String(buffer), typeof(RESTapi.web_service)) as RESTapi.web_service;

                                if (ws != null)
                                {
                                    /// We have an event! We need to pass this to "something"
                                    /// that will determine which call etc. the request belongs
                                    /// to - ie. a call dispatcher.
                                    ///
                                    CallDispatcher <T> .Instance.ProcessRequest(ws);
                                }
                            }
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    HttpWebResponse response = ex.Response as HttpWebResponse;

                    if (response != null)
                    {
                        LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                          "EventDispatcher::InternalProcessEventsThread : Received HTTP failure response {0:D} {1}",
                                                          (int)response.StatusCode, response.StatusDescription);
                    }
                }
                else
                {
                    LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                      "EventDispatcher::InternalProcessEventsThread : {0}\n{1}",
                                                      ex.Message.ToString(), ex.StackTrace.ToString());
                }
            }
            catch (ThreadInterruptedException ex)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                  "EventDispatcher::InternalProcessEventsThread : {0}\n{1}",
                                                  ex.Message.ToString(), ex.StackTrace.ToString());
            }
            catch (Exception ex)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Warning,
                                                  "EventDispatcher::InternalProcessEventsThread : {0}\n{1}",
                                                  ex.Message.ToString(), ex.StackTrace.ToString());
            }

            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug2,
                                              "EventDispatcher::InternalProcessEventsThread : Leaving InternalProcessEventsThread()");
        }