/// <summary> /// Processes the hub's incoming method calls. /// </summary> protected override Task OnReceived(HttpRequest 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)); }