예제 #1
0
        /// <summary>
        /// Does the work of sending a call to the server, and waiting for the response.
        /// </summary>
        /// <param name="jsonRequest">The request to send</param>
        /// <returns>A Task result with the response</returns>
        private Task <TResponse> Send <TResponse>(IApiRequest jsonRequest, string channel, bool silentMode = false) where TResponse : IApiResponse, new()
        {
            TResponse output = default(TResponse);

            return(Task.Run(() =>
            {
                ExceptionUtility.Try(() =>
                {
                    string jsonRequestString = JsonUtility.Serialize(jsonRequest);
                    string jsonRequestStringForLogging = jsonRequestString.Replace(User.Current.Password, "********");
                    LogUtility.LogMessage(String.Format("{2}: Sending Request to {0}: {1}", this.Url, FormatJsonForLogging(jsonRequestStringForLogging), this._instanceId.ToString()));
                    var waitHandle = new AutoResetEvent(false);
                    bool gotResponse = false;

                    Action <IApiResponse> receivedResponse = (r) =>
                    {
                        gotResponse = true;

                        if (r is Lib.Domain.Responses.ConnectionResponse && ((ConnectionResponse)r).IsSuccessful)
                        {
                            NotificationUtility.PostNotification(NotificationType.Reconnected);
                        }

                        if (r is Lib.Domain.Responses.ErrorResponse)
                        {
                            output = ResponseFactory.ParseResponse <TResponse>(r.RawResponse);
                        }
                        else
                        {
                            try
                            {
                                output = (TResponse)r;
                            }
                            catch (System.InvalidCastException ice)
                            {
                                LogUtility.LogException(ice, String.Format("The server returned a type of response that was not expected. The type of response expected was {0}", (typeof(TResponse)).Name), LogSeverity.Warn);
                                output = default(TResponse);
                            }
                        }

                        if (r.IsAuthFailure)
                        {
                            output = ResponseFactory.FabricateLoginFailureResponse <TResponse>(jsonRequest);
                        }

                        gotResponse = true;
                        waitHandle.Set();
                    };

                    RegisterWaitingForResponse(channel, receivedResponse);

                    if (_client != null)
                    {
                        _client.Send(new NSString(jsonRequestString));

                        waitHandle.WaitOne(DefaultSendTimeoutMs);
                        UnregisterWaitingForResponse(channel);
                    }

                    //here we will fabricate an error response for case of timeout
                    if (output == null && !gotResponse)
                    {
                        output = ResponseFactory.FabricateRequestTimeoutResponse <TResponse>(jsonRequest);
                        this.FireRequestFailureEvent(jsonRequest, null, RequestFailureReason.Timeout, foregroundAction: (!silentMode));
                    }
                });

                return output;
            }));
        }