Exemplo n.º 1
0
        private Task ProcessResponse(StateChangeTracker tracker, object result, HubRequest request, Exception error)
        {
            var hubResult = new HubResponse
            {
                State  = tracker.GetChanges(),
                Result = result,
                Id     = request.Id,
            };

            if (error != null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                _counters.ErrorsAllTotal.Increment();
                _counters.ErrorsAllPerSec.Increment();

                if (_enableDetailedErrors)
                {
                    var exception = error.InnerException ?? error;
                    hubResult.StackTrace = _isDebuggingEnabled ? exception.StackTrace : null;
                    hubResult.Error      = exception.Message;
                }
                else
                {
                    hubResult.Error = String.Format(CultureInfo.CurrentCulture, Resources.Error_HubInvocationFailed, request.Hub, request.Method);
                }
            }

            return(Transport.Send(hubResult));
        }
Exemplo n.º 2
0
        private Task ProcessResponse(TrackingDictionary state, object result, HubRequest request, Exception error)
        {
            var    exception    = error.Unwrap();
            string stackTrace   = (exception != null && _isDebuggingEnabled) ? exception.StackTrace : null;
            string errorMessage = exception != null ? exception.Message : null;

            if (exception != null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                _counters.ErrorsAllTotal.Increment();
                _counters.ErrorsAllPerSec.Increment();
            }

            var hubResult = new HubResponse
            {
                State      = state.GetChanges(),
                Result     = result,
                Id         = request.Id,
                Error      = errorMessage,
                StackTrace = stackTrace
            };

            return(_transport.Send(hubResult));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Processes the hub's incoming method calls.
        /// </summary>
        protected override Task OnReceived(IRequest request, string connectionId, string data)
        {
            HubRequest hubRequest = _requestParser.Parse(data, _serializer);

            // Create the hub
            HubDescriptor descriptor = _manager.EnsureHub(hubRequest.Hub,
                                                          _counters.ErrorsHubInvocationTotal,
                                                          _counters.ErrorsHubInvocationPerSec,
                                                          _counters.ErrorsAllTotal,
                                                          _counters.ErrorsAllPerSec);

            IJsonValue[] parameterValues = hubRequest.ParameterValues;

            // Resolve the method

            MethodDescriptor methodDescriptor = _manager.GetHubMethod(descriptor.Name, hubRequest.Method, parameterValues);

            if (methodDescriptor == null)
            {
                // Empty (noop) method descriptor
                // Use: Forces the hub pipeline module to throw an error.  This error is encapsulated in the HubDispatcher.
                //      Encapsulating it in the HubDispatcher prevents the error from bubbling up to the transport level.
                //      Specifically this allows us to return a faulted task (call .fail on client) and to not cause the
                //      transport to unintentionally fail.
                IEnumerable <MethodDescriptor> availableMethods = _manager.GetHubMethods(descriptor.Name, m => m.Name == hubRequest.Method);
                methodDescriptor = new NullMethodDescriptor(descriptor, hubRequest.Method, availableMethods);
            }

            // Resolving the actual state object
            var tracker = new StateChangeTracker(hubRequest.State);
            var hub     = CreateHub(request, descriptor, connectionId, tracker, throwIfFailedToCreate: true);

            return(InvokeHubPipeline(hub, parameterValues, methodDescriptor, hubRequest, tracker)
                   .ContinueWithPreservedCulture(task => hub.Dispose(), TaskContinuationOptions.ExecuteSynchronously));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Processes the hub's incoming method calls.
        /// </summary>
        protected override Task OnReceivedAsync(IRequest request, string connectionId, string data)
        {
            HubRequest hubRequest = _requestParser.Parse(data);

            // Create the hub
            HubDescriptor descriptor = _manager.EnsureHub(hubRequest.Hub,
                                                          _counters.ErrorsHubInvocationTotal,
                                                          _counters.ErrorsHubInvocationPerSec,
                                                          _counters.ErrorsAllTotal,
                                                          _counters.ErrorsAllPerSec);

            IJsonValue[] parameterValues = hubRequest.ParameterValues;

            // Resolve the method
            MethodDescriptor methodDescriptor = _manager.GetHubMethod(descriptor.Name, hubRequest.Method, parameterValues);

            if (methodDescriptor == null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' method could not be resolved.", hubRequest.Method));
            }

            // Resolving the actual state object
            var state = new TrackingDictionary(hubRequest.State);
            var hub   = CreateHub(request, descriptor, connectionId, state, throwIfFailedToCreate: true);

            return(InvokeHubPipeline(request, connectionId, data, hubRequest, parameterValues, methodDescriptor, state, hub)
                   .ContinueWith(task => hub.Dispose(), TaskContinuationOptions.ExecuteSynchronously));
        }
Exemplo n.º 5
0
        private Task ProcessTaskResult <T>(TrackingDictionary state, HubRequest request, Task <T> task)
        {
            if (task.IsFaulted)
            {
                return(ProcessResponse(state, null, request, task.Exception));
            }

            return(ProcessResponse(state, task.Result, request, null));
        }
Exemplo n.º 6
0
        private Task InvokeHubPipeline(IHub hub,
                                       IJsonValue[] parameterValues,
                                       MethodDescriptor methodDescriptor,
                                       HubRequest hubRequest,
                                       StateChangeTracker tracker)
        {
            // TODO: Make adding parameters here pluggable? IValueProvider? ;)
            HubInvocationProgress progress = GetProgressInstance(methodDescriptor, value => SendProgressUpdate(hub.Context.ConnectionId, tracker, value, hubRequest));

            Task <object> piplineInvocation;

            try
            {
                var args = _binder.ResolveMethodParameters(methodDescriptor, parameterValues);

                // We need to add the IProgress<T> instance after resolving the method as the resolution
                // itself looks for overload matches based on the incoming arg values
                if (progress != null)
                {
                    args = args.Concat(new [] { progress }).ToList();
                }

                var context = new HubInvokerContext(hub, tracker, methodDescriptor, args);

                // Invoke the pipeline and save the task
                piplineInvocation = _pipelineInvoker.Invoke(context);
            }
            catch (Exception ex)
            {
                piplineInvocation = TaskAsyncHelper.FromError <object>(ex);
            }

            // Determine if we have a faulted task or not and handle it appropriately.
            return(piplineInvocation.ContinueWithPreservedCulture(task =>
            {
                if (progress != null)
                {
                    // Stop ability to send any more progress updates
                    progress.SetComplete();
                }

                if (task.IsFaulted)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: task.Exception);
                }
                else if (task.IsCanceled)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: new OperationCanceledException());
                }
                else
                {
                    return ProcessResponse(tracker, task.Result, hubRequest, error: null);
                }
            })
                   .FastUnwrap());
        }
Exemplo n.º 7
0
        public HubRequest Parse(string data, JsonSerializer serializer)
        {
            var deserializedData = serializer.Parse <HubInvocation>(data);

            var request = new HubRequest();

            request.Hub             = deserializedData.Hub;
            request.Method          = deserializedData.Method;
            request.Id              = deserializedData.Id;
            request.State           = GetState(deserializedData);
            request.ParameterValues = (deserializedData.Args != null) ? deserializedData.Args.Select(value => new JRawValue(value)).ToArray() : _emptyArgs;

            return(request);
        }
Exemplo n.º 8
0
        public HubRequest Parse(string data, JsonSerializer serializer)
        {
            var deserializedData = serializer.Parse<HubInvocation>(data);

            var request = new HubRequest();

            request.Hub = deserializedData.Hub;
            request.Method = deserializedData.Method;
            request.Id = deserializedData.Id;
            request.State = GetState(deserializedData);
            request.ParameterValues = (deserializedData.Args != null) ? deserializedData.Args.Select(value => new JRawValue(value)).ToArray() : _emptyArgs;

            return request;
        }
Exemplo n.º 9
0
        /// <summary>
        /// Processes the hub's incoming method calls.
        /// </summary>
        protected override Task OnReceivedAsync(IRequest request, string connectionId, string data)
        {
            HubRequest hubRequest = _requestParser.Parse(data);

            // Create the hub
            HubDescriptor descriptor = _manager.EnsureHub(hubRequest.Hub,
                                                          _counters.ErrorsHubInvocationTotal,
                                                          _counters.ErrorsHubInvocationPerSec,
                                                          _counters.ErrorsAllTotal,
                                                          _counters.ErrorsAllPerSec);

            IJsonValue[] parameterValues = hubRequest.ParameterValues;

            // Resolve the method
            MethodDescriptor methodDescriptor = _manager.GetHubMethod(descriptor.Name, hubRequest.Method, parameterValues);

            if (methodDescriptor == null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();

                // Empty (noop) method descriptor
                // Use: Forces the hub pipeline module to throw an error.  This error is encapsulated in the HubDispatcher.
                //      Encapsulating it in the HubDispatcher prevents the error from bubbling up to the transport level.
                //      Specifically this allows us to return a faulted task (call .fail on client) and to not cause the
                //      transport to unintentionally fail.
                methodDescriptor = new MethodDescriptor
                {
                    Invoker = (emptyHub, emptyParameters) =>
                    {
                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.Error_MethodCouldNotBeResolved, hubRequest.Method));
                    },
                    Attributes = new List <Attribute>(),
                    Parameters = new List <ParameterDescriptor>()
                };
            }

            // Resolving the actual state object
            var tracker = new StateChangeTracker(hubRequest.State);
            var hub     = CreateHub(request, descriptor, connectionId, tracker, throwIfFailedToCreate: true);

            return(InvokeHubPipeline(hub, parameterValues, methodDescriptor, hubRequest, tracker)
                   .ContinueWith(task => hub.Dispose(), TaskContinuationOptions.ExecuteSynchronously));
        }
Exemplo n.º 10
0
        public HubRequest Parse(string data)
        {
            var rawRequest = JObject.Parse(data);
            var request = new HubRequest();

            request.Hub = rawRequest.Value<string>("H");
            request.Method = rawRequest.Value<string>("M");
            request.Id = rawRequest.Value<string>("I");

            var rawState = rawRequest["S"];
            request.State = rawState == null ? new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) :
                                       rawState.ToObject<IDictionary<string, object>>();

            var rawArgs = rawRequest["A"];
            request.ParameterValues = rawArgs == null ? _emptyArgs :
                                                rawArgs.Children().Select(value => new JTokenValue(value)).ToArray();

            return request;
        }
Exemplo n.º 11
0
        public HubRequest Parse(string data)
        {
            var rawRequest = JObject.Parse(data);
            var request = new HubRequest();

            // TODO: Figure out case insensitivity in JObject.Parse, this should cover our clients for now
            request.Hub = rawRequest.Value<string>("hub") ?? rawRequest.Value<string>("Hub");
            request.Method = rawRequest.Value<string>("method") ?? rawRequest.Value<string>("Method");
            request.Id = rawRequest.Value<string>("id") ?? rawRequest.Value<string>("Id");

            var rawState = rawRequest["state"] ?? rawRequest["State"];
            request.State = rawState == null ? new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) :
                                       rawState.ToObject<IDictionary<string, object>>();

            var rawArgs = rawRequest["args"] ?? rawRequest["Args"];
            request.ParameterValues = rawArgs == null ? _emptyArgs :
                                                rawArgs.Children().Select(value => new JTokenValue(value)).ToArray();

            return request;
        }
Exemplo n.º 12
0
        public HubRequest Parse(string data)
        {
            var rawRequest = JObject.Parse(data);
            var request    = new HubRequest();

            request.Hub    = rawRequest.Value <string>("H");
            request.Method = rawRequest.Value <string>("M");
            request.Id     = rawRequest.Value <string>("I");

            var rawState = rawRequest["S"];

            request.State = rawState == null ? new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase) :
                            rawState.ToObject <IDictionary <string, object> >();

            var rawArgs = rawRequest["A"];

            request.ParameterValues = rawArgs == null ? _emptyArgs :
                                      rawArgs.Children().Select(value => new JTokenValue(value)).ToArray();

            return(request);
        }
Exemplo n.º 13
0
        private Task ProcessResponse(StateChangeTracker tracker, object result, HubRequest request, Exception error)
        {
            var hubResult = new HubResponse
            {
                State  = tracker.GetChanges(),
                Result = result,
                Id     = request.Id,
            };

            if (error != null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                _counters.ErrorsAllTotal.Increment();
                _counters.ErrorsAllPerSec.Increment();

                var hubError = error.InnerException as HubException;

                if (_enableDetailedErrors || hubError != null)
                {
                    var exception = error.InnerException ?? error;
                    hubResult.StackTrace = _isDebuggingEnabled ? exception.StackTrace : null;
                    hubResult.Error      = exception.Message;

                    if (hubError != null)
                    {
                        hubResult.IsHubException = true;
                        hubResult.ErrorData      = hubError.ErrorData;
                    }
                }
                else
                {
                    hubResult.Error = String.Format(CultureInfo.CurrentCulture, Resources.Error_HubInvocationFailed, request.Hub, request.Method);
                }
            }

            Trace.TraceVerbose("Sending hub invocation result to connection {0} using transport {1}", Transport.ConnectionId, Transport.GetType().Name);

            return(Transport.Send(hubResult));
        }
Exemplo n.º 14
0
        private Task InvokeHubPipeline(IHub hub,
                                       IJsonValue[] parameterValues,
                                       MethodDescriptor methodDescriptor,
                                       HubRequest hubRequest,
                                       StateChangeTracker tracker)
        {
            Task <object> piplineInvocation;

            try
            {
                var args    = _binder.ResolveMethodParameters(methodDescriptor, parameterValues);
                var context = new HubInvokerContext(hub, tracker, methodDescriptor, args);

                // Invoke the pipeline and save the task
                piplineInvocation = _pipelineInvoker.Invoke(context);
            }
            catch (Exception ex)
            {
                piplineInvocation = TaskAsyncHelper.FromError <object>(ex);
            }

            // Determine if we have a faulted task or not and handle it appropriately.
            return(piplineInvocation.ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: task.Exception);
                }
                else if (task.IsCanceled)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: new OperationCanceledException());
                }
                else
                {
                    return ProcessResponse(tracker, task.Result, hubRequest, error: null);
                }
            })
                   .FastUnwrap());
        }
Exemplo n.º 15
0
        public HubRequest Parse(string data)
        {
            var rawRequest = JObject.Parse(data);
            var request    = new HubRequest();

            // TODO: Figure out case insensitivity in JObject.Parse, this should cover our clients for now
            request.Hub    = rawRequest.Value <string>("hub") ?? rawRequest.Value <string>("Hub");
            request.Method = rawRequest.Value <string>("method") ?? rawRequest.Value <string>("Method");
            request.Id     = rawRequest.Value <string>("id") ?? rawRequest.Value <string>("Id");

            var rawState = rawRequest["state"] ?? rawRequest["State"];

            request.State = rawState == null ? new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase) :
                            rawState.ToObject <IDictionary <string, object> >();

            var rawArgs = rawRequest["args"] ?? rawRequest["Args"];

            request.ParameterValues = rawArgs == null ? _emptyArgs :
                                      rawArgs.Children().Select(value => new JTokenValue(value)).ToArray();

            return(request);
        }
Exemplo n.º 16
0
        private Task InvokeHubPipeline(IRequest request, string connectionId, string data, HubRequest hubRequest, IJsonValue[] parameterValues, MethodDescriptor methodDescriptor, TrackingDictionary state, IHub hub)
        {
            var args    = _binder.ResolveMethodParameters(methodDescriptor, parameterValues);
            var context = new HubInvokerContext(hub, state, methodDescriptor, args);

            // Invoke the pipeline
            return(_pipelineInvoker.Invoke(context)
                   .ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    return ProcessResponse(state, null, hubRequest, task.Exception);
                }
                else
                {
                    return ProcessResponse(state, task.Result, hubRequest, null);
                }
            })
                   .FastUnwrap());
        }
Exemplo n.º 17
0
        private Task SendProgressUpdate(string connectionId, StateChangeTracker tracker, object value, HubRequest request)
        {
            var hubResult = new HubResponse
            {
                State    = tracker.GetChanges(),
                Progress = new { I = request.Id, D = value },
                // We prefix the ID here to ensure old clients treat this as a hub response
                // but fail to lookup a corresponding callback and thus no-op
                Id = "P|" + request.Id,
            };

            return(Connection.Send(connectionId, hubResult));
        }