示例#1
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)
            {
                _hubInvocationErrorsTotalCounter.SafeIncrement();
                _hubInvocationErrorsPerSecCounter.SafeIncrement();
                _allErrorsTotalCounter.SafeIncrement();
                _allErrorsPerSecCounter.SafeIncrement();
            }

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

            return(_transport.Send(hubResult));
        }
示例#2
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));
        }
示例#3
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));
 }
示例#4
0
        private void ProcessResult(TrackingDictionary state, object result, HubRequest request, Exception error)
        {
            var hubResult = new HubResult
            {
                State  = state.GetChanges(),
                Result = result,
                Id     = request.Id,
                Error  = error != null?error.GetBaseException().Message : null
            };

            Send(hubResult);
        }
示例#5
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;

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

            return(_transport.Send(hubResult));
        }
示例#6
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;
        }
示例#7
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);
        }
示例#8
0
        private Task ProcessResult(TrackingDictionary state, object result, HubRequest request, Exception error)
        {
            var hubResult = new HubResult
            {
                State = state.GetChanges(),
                Result = result,
                Id = request.Id,
                Error = error != null ? error.GetBaseException().Message : null
            };

            return Send(hubResult);
        }
示例#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,
                                                          _hubResolutionErrorsTotalCounter,
                                                          _hubResolutionErrorsPerSecCounter,
                                                          _allErrorsTotalCounter,
                                                          _allErrorsPerSecCounter);

            IJsonValue[] parameterValues = hubRequest.ParameterValues;

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

            if (methodDescriptor == null)
            {
                _hubResolutionErrorsTotalCounter.SafeIncrement();
                _hubResolutionErrorsPerSecCounter.SafeIncrement();
                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);

            Task resultTask;

            try
            {
                // Invoke the method
                object result     = methodDescriptor.Invoker.Invoke(hub, _binder.ResolveMethodParameters(methodDescriptor, parameterValues));
                Type   returnType = result != null?result.GetType() : methodDescriptor.ReturnType;

                if (typeof(Task).IsAssignableFrom(returnType))
                {
                    var task = (Task)result;
                    if (!returnType.IsGenericType)
                    {
                        return(task.ContinueWith(t => ProcessResponse(state, null, hubRequest, t.Exception))
                               .FastUnwrap());
                    }
                    else
                    {
                        // Get the <T> in Task<T>
                        Type resultType = returnType.GetGenericArguments().Single();

                        // Get the correct ContinueWith overload
                        var continueWith = TaskAsyncHelper.GetContinueWith(task.GetType());

                        var taskParameter       = Expression.Parameter(continueWith.Type);
                        var processResultMethod = typeof(HubDispatcher).GetMethod("ProcessTaskResult", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(resultType);

                        var body = Expression.Call(Expression.Constant(this),
                                                   processResultMethod,
                                                   Expression.Constant(state),
                                                   Expression.Constant(hubRequest),
                                                   taskParameter);

                        var lambda = Expression.Lambda(body, taskParameter);

                        var call = Expression.Call(Expression.Constant(task, continueWith.Type), continueWith.Method, lambda);
                        Func <Task <Task> > continueWithMethod = Expression.Lambda <Func <Task <Task> > >(call).Compile();
                        return(continueWithMethod.Invoke().FastUnwrap());
                    }
                }
                else
                {
                    resultTask = ProcessResponse(state, result, hubRequest, null);
                }
            }
            catch (TargetInvocationException e)
            {
                resultTask = ProcessResponse(state, null, hubRequest, e);
            }

            return(resultTask.Then(() => base.OnReceivedAsync(request, connectionId, data))
                   .Catch());
        }
示例#10
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());
        }