Ejemplo n.º 1
1
        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;
        }
Ejemplo n.º 2
1
            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());
            }
Ejemplo n.º 3
0
 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);
        }
Ejemplo n.º 5
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,
                                                          _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));
        }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
        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;
        }
Ejemplo n.º 8
0
        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());
        }
Ejemplo n.º 9
0
 public SignalAgent(IConnection connection, string signal, string hubName, TrackingDictionary state)
 {
     _connection = connection;
     _signal = signal;
     _hubName = hubName;
     _state = state;
 }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
 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);
        }
Ejemplo n.º 13
0
            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);
            }
Ejemplo n.º 14
0
        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);
        }
Ejemplo n.º 15
0
        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));
        }
Ejemplo n.º 16
0
            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);
            }
Ejemplo n.º 17
0
        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);
        }
Ejemplo n.º 18
0
        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);
        }
Ejemplo n.º 19
0
            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);
            }
Ejemplo n.º 20
0
            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);
            }
Ejemplo n.º 21
0
        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();
                }
            }
        }
Ejemplo n.º 22
0
        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);
        }
Ejemplo n.º 23
0
        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();
        }
Ejemplo n.º 24
0
        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();
                }
            }
        }
Ejemplo n.º 25
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());
        }
Ejemplo n.º 26
0
        /// <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;
        }
Ejemplo n.º 27
0
 public StatefulSignalProxy(IConnection connection, string signal, string hubName, TrackingDictionary state)
     : base(connection, signal, hubName)
 {
     _state = state;
 }
Ejemplo n.º 28
0
 public static TestableChat GetTestableChat(string clientId, TrackingDictionary clientState, ChatUser user)
 {
     return GetTestableChat(clientId, clientState, user, new NameValueCollection());
 }
Ejemplo n.º 29
0
        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());
        }
Ejemplo n.º 30
0
        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));
        }
Ejemplo n.º 31
0
        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());
        }
Ejemplo n.º 32
0
 public StatefulSignalProxy(Func <string, ClientHubInvocation, Task> send, string signal, string hubName, TrackingDictionary state)
     : base(send, signal, hubName)
 {
     _state = state;
 }
Ejemplo n.º 33
0
 public StatefulSignalProxy(IConnection connection, string signal, string hubName, TrackingDictionary state)
     : base(connection, signal, hubName)
 {
     _state = state;
 }
Ejemplo n.º 34
0
        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);
            }
        }
Ejemplo n.º 35
0
            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());
            }
Ejemplo n.º 36
0
 public StatefulSignalProxy(Func<string, ClientHubInvocation, Task> send, string signal, string hubName, TrackingDictionary state)
     : base(send, signal, hubName)
 {
     _state = state;
 }