protected override Task OnReceived(HostContext context, string data)
        {
            Trace.WriteLine($"OnReceived : { data }");
            var request = Newtonsoft.Json.JsonConvert.DeserializeObject <Message>(data);

            var setting = new Newtonsoft.Json.JsonSerializerSettings
            {
                TypeNameHandling      = Newtonsoft.Json.TypeNameHandling.All,
                MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Error
            };

            var hubDescriptor    = _manager.GetHub(request.Value.Hub);
            var methodDescriptor = _manager.GetHubMethod(hubDescriptor.Name, request.Value.Method, request.Value.Args.ToArray());
            var hub = _activator.Create(hubDescriptor);

            hub.Clients = new HubConnectionContextBase(hubDescriptor.Name, Connection, _pipelineInvoker);
            methodDescriptor.Invoke(hub, request.Value.Args.Select((r, index) =>
            {
                return(JsonSerializer.Deserialize(JToken.FromObject(r), methodDescriptor.Parameters[index].ParameterType));
            }).ToArray());
            hub.Dispose();

            return(base.OnReceived(context, data));
        }
Beispiel #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,
                                                          _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());
        }