public async Task <IHttpActionResult> ReconnectAndInvoke(string connectionId, string hubName, string methodName, [FromBody] HubNamesAndArguments hubNamesAndArguments) { Session session; bool sessionRetrieved; sessionManagementLock.EnterReadLock(); try { sessionRetrieved = sessions.TryGetValue(connectionId, out session); } finally { sessionManagementLock.ExitReadLock(); } var hubMethodInvocation = new HubMethodInvocation { Arguments = hubNamesAndArguments.Arguments, Hub = hubName, Method = methodName }; if (!sessionRetrieved) { try { session = await PerformConnect(hubNamesAndArguments.HubNames, connectionId); } catch (ArgumentOutOfRangeException) { return(NotFound()); } return(Ok(new { ConnectionId = session.ConnectionId, ReturnValue = await ExecuteHubMethodInvocation(session, Request, hubMethodInvocation) })); } if (!session.Hubs.Keys.OrderBy(n => n).SequenceEqual(hubNamesAndArguments.HubNames.OrderBy(n => n), StringComparer.OrdinalIgnoreCase)) { return(Conflict()); } return(Ok(new { Events = GetEvents(session), ReturnValue = await ExecuteHubMethodInvocation(session, Request, hubMethodInvocation) })); }
static async Task <object> ExecuteHubMethodInvocation(Session session, HttpRequestMessage requestMessage, HubMethodInvocation invocation) { object invocationResult = null; ReflectedHub reflectedHub; if (!Hubs.TryGetValue(invocation.Hub, out reflectedHub)) { invocationResult = new { Error = "Hub not found" } } ; else { IReadOnlyDictionary <int, Tuple <Type, Type[], FastMethodInfo> > overloads; if (!reflectedHub.MethodNames.TryGetValue(invocation.Method, out overloads)) { invocationResult = new { Error = "Hub method not found" } } ; else { Tuple <Type, Type[], FastMethodInfo> overload; if (!overloads.TryGetValue(invocation.Arguments?.Count ?? 0, out overload)) { invocationResult = new { Error = "Hub method not found" } } ; else { var argumentsList = new List <object>(); var p = -1; if (invocation.Arguments != null) { foreach (var child in invocation.Arguments.Children()) { argumentsList.Add(child.ToObject(overload.Item2[++p])); } } try { using (var hub = Hub.GetHub(requestMessage, invocation.Hub, session)) invocationResult = overload.Item3.Invoke(hub, argumentsList.ToArray()); if (invocationResult != null) { var task = invocationResult as Task; if (task != null) { await task.ContinueWith(t => { if (t.IsFaulted) { invocationResult = new { Error = string.Format("{0}: {1}", t.Exception.GetType().Name, t.Exception.Message) } } ; else { var type = t.GetType(); if (type.IsGenericType) { invocationResult = taskValueGetters.GetOrAdd(type, CreateTaskValueGetter).Invoke(t); } } }); } } } catch (Exception ex) { invocationResult = new { Error = string.Format("{0}: {1}", ex.GetType().Name, ex.Message) }; } } } } return(invocationResult); }