public override void Initialize(IDependencyResolver resolver, HostContext context) { if (resolver == null) { throw new ArgumentNullException("resolver"); } if (context == null) { throw new ArgumentNullException("context"); } _proxyGenerator = resolver.Resolve <IJavaScriptProxyGenerator>(); _manager = resolver.Resolve <IHubManager>(); _binder = resolver.Resolve <IParameterResolver>(); _requestParser = resolver.Resolve <IHubRequestParser>(); _pipelineInvoker = resolver.Resolve <IHubPipelineInvoker>(); _counters = resolver.Resolve <IPerformanceCounterManager>(); // Call base initializer before populating _hubs so the _jsonSerializer is initialized base.Initialize(resolver, context); // Populate _hubs string data = context.Request.QueryStringOrForm("connectionData"); if (!String.IsNullOrEmpty(data)) { var clientHubInfo = JsonSerializer.Parse <IEnumerable <ClientHubInfo> >(data); if (clientHubInfo != null) { foreach (var hubInfo in clientHubInfo) { // Try to find the associated hub type HubDescriptor hubDescriptor = _manager.EnsureHub(hubInfo.Name, _counters.ErrorsHubResolutionTotal, _counters.ErrorsHubResolutionPerSec, _counters.ErrorsAllTotal, _counters.ErrorsAllPerSec); if (_pipelineInvoker.AuthorizeConnect(hubDescriptor, context.Request)) { // Add this to the list of hub descriptors this connection is interested in _hubs.Add(hubDescriptor); } } } } }
/// <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()); }