public static TestableChat GetTestableChat(string clientId, TrackingDictionary clientState, ChatUser user, NameValueCollection cookies) { // setup things needed for chat var repository = new InMemoryRepository(); var resourceProcessor = new Mock<IResourceProcessor>(); var chatService = new Mock<IChatService>(); var connection = new Mock<IConnection>(); // add user to repository repository.Add(user); // create testable chat var chat = new TestableChat(resourceProcessor, chatService, repository, connection); var mockedConnectionObject = chat.MockedConnection.Object; // setup client agent chat.Agent = new ClientAgent(mockedConnectionObject, "Chat"); var request = new Mock<IRequest>(); request.Setup(m => m.Cookies).Returns(cookies); // setup signal agent var prinicipal = new Mock<IPrincipal>(); chat.Caller = new SignalAgent(mockedConnectionObject, clientId, "Chat", clientState); // setup context chat.Context = new HubContext(new HostContext(request.Object, null, prinicipal.Object), clientId); return chat; }
public void CanDeserializeClientState() { var clientState = new TrackingDictionary(); string clientId = "1"; var user = new ChatUser { Id = "1234", Name = "John" }; var cookies = new NameValueCollection(); cookies["jabbr.state"] = JsonConvert.SerializeObject(new ClientState { UserId = user.Id }); TestableChat chat = GetTestableChat(clientId, clientState, user, cookies); bool result = chat.Join(); Assert.Equal("1234", clientState["id"]); Assert.Equal("John", clientState["name"]); Assert.True(result); chat.MockedConnection.Verify(m => m.Broadcast("Chat." + clientId, It.IsAny<object>()), Times.Once()); chat.MockedChatService.Verify(c => c.AddClient(user, clientId), Times.Once()); chat.MockedChatService.Verify(c => c.UpdateActivity(user), Times.Once()); }
public SignalAgent(IConnection connection, string signal, string hubName, TrackingDictionary state) { _connection = connection; _signal = signal; _hubName = hubName; _state = state; }
protected override void Initialize(HttpControllerContext controllerContext) { var hub = ((IHub)this); var hubName = this.GetType().FullName; var hubManager = _resolver.Resolve<IHubManager>(); var descriptor = hubManager.EnsureHub(hubName); var user = controllerContext.Request.GetUserPrincipal(); // Response parameter is null here because outgoing broadcast messages will always go // via the SignalR intrinsics, and method return values via the Web API intrinsics. var hostContext = new HostContext(new WebApiRequest(controllerContext.Request), null, user); var connectionId = hostContext.Request.QueryString["connectionId"]; hub.Context = new HubContext(hostContext, connectionId); var connection = _resolver.Resolve<IConnectionManager>().GetConnection<HubDispatcher>(); var state = new TrackingDictionary(); var agent = new ClientAgent(connection, descriptor.Name); hub.Caller = new SignalAgent(connection, connectionId, descriptor.Name, state); hub.Agent = agent; hub.GroupManager = agent; base.Initialize(controllerContext); }
/// <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)); }
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)); }
public static TestableChat GetTestableChat(string connectionId, TrackingDictionary clientState, ChatUser user, NameValueCollection cookies) { // setup things needed for chat var repository = new InMemoryRepository(); var resourceProcessor = new Mock<IResourceProcessor>(); var chatService = new Mock<IChatService>(); var connection = new Mock<IConnection>(); var settings = new Mock<IApplicationSettings>(); settings.Setup(m => m.AuthApiKey).Returns("key"); // add user to repository repository.Add(user); // create testable chat var chat = new TestableChat(settings, resourceProcessor, chatService, repository, connection); var mockedConnectionObject = chat.MockedConnection.Object; // setup client agent chat.Clients = new ClientProxy(mockedConnectionObject, "Chat"); // setup signal agent var prinicipal = new Mock<IPrincipal>(); var request = new Mock<IRequest>(); request.Setup(m => m.Cookies).Returns(new Cookies(cookies)); request.Setup(m => m.User).Returns(prinicipal.Object); chat.Caller = new StatefulSignalProxy(mockedConnectionObject, connectionId, "Chat", clientState); // setup context chat.Context = new HubCallerContext(request.Object, connectionId); return chat; }
public void JoinCallsAddUserIfValidUserIdInCookieAndUserList() { var repository = new ChatRepository(); var user = new ChatUser { Id = "1234", Name = "John", Hash = "Hash" }; repository.Users.Add(user); var chat = new ChatHub(repository); var connection = new Mock<IConnection>(); var prinicipal = new Mock<IPrincipal>(); var cookies = new HttpCookieCollection(); cookies.Add(new HttpCookie("userid", "1234")); var clientState = new TrackingDictionary(); string clientId = "20"; chat.Agent = new ClientAgent(connection.Object, "Chat"); chat.Caller = new SignalAgent(connection.Object, clientId, "Chat", clientState); chat.Context = new HubContext(clientId, cookies, prinicipal.Object); chat.Join(); Assert.Equal("1234", clientState["id"]); Assert.Equal("John", clientState["name"]); Assert.Equal("Hash", clientState["hash"]); Assert.Equal("20", user.ClientId); // Need a better way to verify method name and arguments connection.Verify(m => m.Broadcast("Chat.20", It.IsAny<object>()), Times.Once()); }
public SignalAgent(IConnection connection, string signal, string hubName, TrackingDictionary state) { _connection = connection; _signal = signal; _hubName = hubName; _state = state; }
protected override Task OnDisconnectAsync(string connectionId) { // Loop over each hub and call disconnect (if the hub supports it) foreach (Type type in GetDisconnectTypes()) { string hubName = type.FullName; IHub hub = _hubFactory.CreateHub(hubName); var disconnect = hub as IDisconnect; if (disconnect != null) { // REVIEW: We don't have any client state here since we're calling this from the server. // Will this match user expectations? var state = new TrackingDictionary(); hub.Context = new HubContext(_context, connectionId); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; disconnect.Disconnect(); } } return(TaskAsyncHelper.Empty); }
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)); }
/// <summary> /// Initializes a new instance of the <see cref="HubConnectionContext"/>. /// </summary> /// <param name="pipelineInvoker">The pipeline invoker.</param> /// <param name="connection">The connection.</param> /// <param name="hubName">The hub name.</param> /// <param name="connectionId">The connection id.</param> /// <param name="state">The connection hub state.</param> public HubConnectionContext(IHubPipelineInvoker pipelineInvoker, IConnection connection, string hubName, string connectionId, TrackingDictionary state) { _send = (signal, invocation, exclude) => pipelineInvoker.Send(new HubOutgoingInvokerContext(connection, signal, invocation, exclude)); _connectionId = connectionId; _hubName = hubName; Caller = new StatefulSignalProxy(_send, connectionId, hubName, state); All = AllExcept(); Others = AllExcept(connectionId); }
public void MissingUsernameReturnsFalse() { var clientState = new TrackingDictionary(); string clientId = "1"; var user = new ChatUser(); TestableChat chat = GetTestableChat(clientId, clientState, user); bool result = chat.Join(); Assert.False(result); }
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); }
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)); }
public void CannotJoinChat() { var clientState = new TrackingDictionary(); string clientId = "1"; var user = new ChatUser { Id = "1234", Name = "John" }; TestableChat chat = GetTestableChat(clientId, clientState, user); chat.Caller.id = "1234"; bool result = chat.Join(); Assert.False(result); }
public void JoinReturnsFalseIfNoCookies() { var repository = new ChatRepository(); var chat = new ChatHub(repository); var connection = new Mock<IConnection>(); var prinicipal = new Mock<IPrincipal>(); var clientState = new TrackingDictionary(); string clientId = "test"; chat.Agent = new ClientAgent(connection.Object, "Chat"); chat.Caller = new SignalAgent(connection.Object, clientId, "Chat", clientState); chat.Context = new HubContext(clientId, new HttpCookieCollection(), prinicipal.Object); bool result = chat.Join(); string versionString = typeof(ChatHub).Assembly.GetName().Version.ToString(); Assert.Equal(versionString, clientState["version"]); Assert.False(result); }
public TestableDebugHub(Mock<IContext> mockDbContext) : base(mockDbContext.Object) { const string connectionId = "1234"; const string hubName = "debug"; var mockConn = new Mock<IConnection>(); var mockUser = new Mock<IPrincipal>(); var mockCookies = new Mock<IRequestCookieCollection>(); var mockRequest = new Mock<IRequest>(); mockRequest.Setup(r => r.User).Returns(mockUser.Object); mockRequest.Setup(r => r.Cookies).Returns(mockCookies.Object); Clients = new ClientProxy(mockConn.Object, hubName); Groups = new GroupManager(mockConn.Object, hubName); Context = new HubCallerContext(mockRequest.Object, connectionId); var trackingDict = new TrackingDictionary(); Caller = new StatefulSignalProxy(mockConn.Object, connectionId, hubName, trackingDict); }
public void CanDeserializeClientState() { var clientState = new TrackingDictionary(); string clientId = "1"; var user = new ChatUser { Id = "1234", Name = "John", Identity = "foo" }; var cookies = new NameValueCollection(); cookies["jabbr.state"] = JsonConvert.SerializeObject(new ClientState { UserId = user.Id }); TestableChat chat = GetTestableChat(clientId, clientState, user, cookies); bool result = chat.Join(); Assert.Equal("1234", clientState["id"]); Assert.Equal("John", clientState["name"]); Assert.True(result); }
public void CanJoinChatIfIdentitySet() { var clientState = new TrackingDictionary(); string clientId = "1"; var user = new ChatUser { Id = "1234", Name = "John", Identity = "foo" }; TestableChat chat = GetTestableChat(clientId, clientState, user); chat.Caller.id = "1234"; bool result = chat.Join(); Assert.Equal("1234", clientState["id"]); Assert.Equal("John", clientState["name"]); Assert.True(result); // TODO: find out why these don't work //Assert.Equal(1, user.ConnectedClients.Count); //Assert.Equal("1", user.ConnectedClients.First().Id); }
protected override void OnDisconnect(string clientId) { // Loop over each hub and call disconnect (if the hub supports it) foreach (Type type in _hubLocator.GetHubs()) { string hubName = type.FullName; IHub hub = _hubFactory.CreateHub(hubName); var disconnect = hub as IDisconnect; if (disconnect != null) { // REVIEW: We don't have any client state here since we're calling this from the server. // Will this match user expectations? var state = new TrackingDictionary(); hub.Context = new HubContext(clientId, _cookies, _user); hub.Caller = new SignalAgent(Connection, clientId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; disconnect.Disconnect(); } } }
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); }
protected override Task OnReceivedAsync(string connectionId, string data) { var hubRequest = _serializer.Deserialize<HubRequest>(data); // Create the hub IHub hub = _hubFactory.CreateHub(hubRequest.Hub); // Deserialize the parameter name value pairs so we can match it up with the method's parameters var parameters = hubRequest.Data; // Resolve the action ActionInfo actionInfo = _actionResolver.ResolveAction(hub.GetType(), hubRequest.Action, parameters); if (actionInfo == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' could not be resolved.", hubRequest.Action)); } string hubName = hub.GetType().FullName; var state = new TrackingDictionary(hubRequest.State); hub.Context = new HubContext(connectionId, _cookies, _user); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; Task resultTask; try { // Execute the method object result = actionInfo.Method.Invoke(hub, actionInfo.Arguments); Type returnType = result != null ? result.GetType() : actionInfo.Method.ReturnType; if (typeof(Task).IsAssignableFrom(returnType)) { var task = (Task)result; if (!returnType.IsGenericType) { return task.ContinueWith(t => ProcessResult(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("ProcessResult", BindingFlags.NonPublic | BindingFlags.Instance); var taskResult = Expression.Property(taskParameter, "Result"); var taskException = Expression.Property(taskParameter, "Exception"); var body = Expression.Call(Expression.Constant(this), processResultMethod, Expression.Constant(state), Expression.Convert(taskResult, typeof(object)), Expression.Constant(hubRequest), Expression.Convert(taskException, typeof(Exception))); var lambda = Expression.Lambda(body, taskParameter); var call = Expression.Call(Expression.Constant(task, continueWith.Type), continueWith.Method, lambda); return Expression.Lambda<Func<Task<Task>>>(call).Compile()().FastUnwrap(); } } else { resultTask = ProcessResult(state, result, hubRequest, null); } } catch (TargetInvocationException e) { resultTask = ProcessResult(state, null, hubRequest, e); } return resultTask .ContinueWith(_ => base.OnReceivedAsync(connectionId, data)) .FastUnwrap(); }
protected override void OnDisconnect(string connectionId) { // Loop over each hub and call disconnect (if the hub supports it) foreach (Type type in GetDisconnectTypes()) { string hubName = type.FullName; IHub hub = _hubFactory.CreateHub(hubName); var disconnect = hub as IDisconnect; if (disconnect != null) { // REVIEW: We don't have any client state here since we're calling this from the server. // Will this match user expectations? var state = new TrackingDictionary(); hub.Context = new HubContext(connectionId, _cookies, _user); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; disconnect.Disconnect(); } } }
/// <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()); }
/// <summary> /// /// </summary> /// <param name="pipelineInvoker"></param> /// <param name="connection"></param> /// <param name="hubName"></param> /// <param name="connectionId"></param> /// <param name="state"></param> public HubConnectionContext(IHubPipelineInvoker pipelineInvoker, IConnection connection, string hubName, string connectionId, TrackingDictionary state) { _send = (signal, invocation, exclude) => pipelineInvoker.Send(new HubOutgoingInvokerContext(connection, signal, invocation, exclude)); _connectionId = connectionId; _hubName = hubName; Caller = new StatefulSignalProxy(_send, connectionId, hubName, state); All = AllExcept(); Others = AllExcept(connectionId); Connection = connection; }
public StatefulSignalProxy(IConnection connection, string signal, string hubName, TrackingDictionary state) : base(connection, signal, hubName) { _state = state; }
public static TestableChat GetTestableChat(string clientId, TrackingDictionary clientState, ChatUser user) { return GetTestableChat(clientId, clientState, user, new NameValueCollection()); }
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()); }
protected override Task OnReceivedAsync(string clientId, string data) { var hubRequest = _serializer.Deserialize <HubRequest>(data); // Create the hub IHub hub = _hubFactory.CreateHub(hubRequest.Hub); // Deserialize the parameter name value pairs so we can match it up with the method's parameters var parameters = hubRequest.Data; // Resolve the action ActionInfo actionInfo = _actionResolver.ResolveAction(hub.GetType(), hubRequest.Action, parameters); if (actionInfo == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' could not be resolved.", hubRequest.Action)); } string hubName = hub.GetType().FullName; var state = new TrackingDictionary(hubRequest.State); hub.Context = new HubContext(clientId, _cookies, _user); hub.Caller = new SignalAgent(Connection, clientId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; try { // Execute the method object result = actionInfo.Method.Invoke(hub, actionInfo.Arguments); Type returnType = result != null?result.GetType() : actionInfo.Method.ReturnType; if (typeof(Task).IsAssignableFrom(returnType)) { var task = (Task)result; if (!returnType.IsGenericType) { return(task.ContinueWith(t => ProcessResult(state, null, hubRequest, t.Exception))); } else { // Get the <T> in Task<T> Type resultType = returnType.GetGenericArguments().Single(); // Get the correct ContinueWith overload var continueWith = (from m in task.GetType().GetMethods() let methodParameters = m.GetParameters() where m.Name.Equals("ContinueWith", StringComparison.OrdinalIgnoreCase) && methodParameters.Length == 1 let parameter = methodParameters[0] where parameter.ParameterType.IsGenericType && typeof(Action <>) == parameter.ParameterType.GetGenericTypeDefinition() select new { Method = m, ArgType = parameter.ParameterType.GetGenericArguments()[0] }) .FirstOrDefault(); var taskParameter = Expression.Parameter(continueWith.ArgType); var processResultMethod = typeof(HubDispatcher).GetMethod("ProcessResult", BindingFlags.NonPublic | BindingFlags.Instance); var taskResult = Expression.Property(taskParameter, "Result"); var taskException = Expression.Property(taskParameter, "Exception"); var body = Expression.Call(Expression.Constant(this), processResultMethod, Expression.Constant(state), Expression.Convert(taskResult, typeof(object)), Expression.Constant(hubRequest), Expression.Convert(taskException, typeof(Exception))); var lambda = Expression.Lambda(body, taskParameter); var call = Expression.Call(Expression.Constant(task, continueWith.ArgType), continueWith.Method, lambda); return(Expression.Lambda <Func <Task> >(call).Compile()()); } } else { ProcessResult(state, result, hubRequest, null); } } catch (TargetInvocationException e) { ProcessResult(state, null, hubRequest, e); } return(base.OnReceivedAsync(clientId, data)); }
protected override Task OnReceivedAsync(string connectionId, string data) { var hubRequest = _serializer.Deserialize <HubRequest>(data); // Create the hub IHub hub = _hubFactory.CreateHub(hubRequest.Hub); // Deserialize the parameter name value pairs so we can match it up with the method's parameters var parameters = hubRequest.Data; // Resolve the action ActionInfo actionInfo = _actionResolver.ResolveAction(hub.GetType(), hubRequest.Action, parameters); if (actionInfo == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' could not be resolved.", hubRequest.Action)); } string hubName = hub.GetType().FullName; var state = new TrackingDictionary(hubRequest.State); hub.Context = new HubContext(_context, connectionId); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; Task resultTask; try { // Execute the method object result = actionInfo.Method.Invoke(hub, actionInfo.Arguments); Type returnType = result != null?result.GetType() : actionInfo.Method.ReturnType; if (typeof(Task).IsAssignableFrom(returnType)) { var task = (Task)result; if (!returnType.IsGenericType) { return(task.ContinueWith(t => ProcessResult(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 = ProcessResult(state, result, hubRequest, null); } } catch (TargetInvocationException e) { resultTask = ProcessResult(state, null, hubRequest, e); } return(resultTask .ContinueWith(_ => base.OnReceivedAsync(connectionId, data)) .FastUnwrap()); }
public StatefulSignalProxy(Func <string, ClientHubInvocation, Task> send, string signal, string hubName, TrackingDictionary state) : base(send, signal, hubName) { _state = state; }
public StatefulSignalProxy(IConnection connection, string signal, string hubName, TrackingDictionary state) : base(connection, signal, hubName) { _state = state; }
private IHub CreateHub(IRequest request, HubDescriptor descriptor, string connectionId, TrackingDictionary state = null, bool throwIfFailedToCreate = false) { try { var hub = _manager.ResolveHub(descriptor.Name); if (hub != null) { state = state ?? new TrackingDictionary(); hub.Context = new HubCallerContext(request, connectionId); hub.Caller = new StatefulSignalProxy(Connection, connectionId, descriptor.Name, state); hub.Clients = new ClientProxy(Connection, descriptor.Name); hub.Groups = new GroupManager(Connection, descriptor.Name); } return(hub); } catch (Exception ex) { Trace.TraceInformation("Error creating hub {0}. " + ex.Message, descriptor.Name); if (throwIfFailedToCreate) { throw; } return(null); } }
public void CanJoinChat() { var clientState = new TrackingDictionary(); string clientId = "1"; var user = new ChatUser { Id = "1234", Name = "John" }; TestableChat chat = GetTestableChat(clientId, clientState, user); chat.Caller.id = "1234"; bool result = chat.Join(); Assert.Equal("1234", clientState["id"]); Assert.Equal("John", clientState["name"]); Assert.True(result); // TODO: find out why these don't work //Assert.Equal(1, user.ConnectedClients.Count); //Assert.Equal("1", user.ConnectedClients.First().Id); chat.MockedConnection.Verify(m => m.Broadcast("Chat." + clientId, It.IsAny<object>()), Times.Once()); chat.MockedChatService.Verify(c => c.AddClient(user, clientId), Times.Once()); chat.MockedChatService.Verify(c => c.UpdateActivity(user), Times.Once()); }
public StatefulSignalProxy(Func<string, ClientHubInvocation, Task> send, string signal, string hubName, TrackingDictionary state) : base(send, signal, hubName) { _state = state; }