A change tracking dictionary.
Exemplo n.º 1
6
        public static TestableChat GetTestableChat(string connectionId, StateChangeTracker clientState, ChatUser user, IDictionary<string, Cookie> 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>();
            var mockPipeline = new Mock<IHubPipelineInvoker>();

            // add user to repository
            repository.Add(user);

            // create testable chat
            var chat = new TestableChat(settings, resourceProcessor, chatService, repository, connection);
            var mockedConnectionObject = chat.MockedConnection.Object;

            chat.Clients = new HubConnectionContext(mockPipeline.Object, mockedConnectionObject, "Chat", connectionId, clientState);

            var prinicipal = new Mock<IPrincipal>();

            var request = new Mock<IRequest>();
            request.Setup(m => m.Cookies).Returns(cookies);
            request.Setup(m => m.User).Returns(prinicipal.Object);

            // setup context
            chat.Context = new HubCallerContext(request.Object, connectionId);

            return chat;
        }
Exemplo n.º 2
0
 public HubInvokerContext(IHub hub, StateChangeTracker tracker, MethodDescriptor methodDescriptor, IList<object> args)
 {
     Hub = hub;
     MethodDescriptor = methodDescriptor;
     Args = args;
     StateTracker = tracker;
 }
Exemplo n.º 3
0
        private Task ProcessResponse(StateChangeTracker tracker, object result, HubRequest request, Exception error)
        {
            var hubResult = new HubResponse
            {
                State  = tracker.GetChanges(),
                Result = result,
                Id     = request.Id,
            };

            if (error != null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                _counters.ErrorsAllTotal.Increment();
                _counters.ErrorsAllPerSec.Increment();

                if (_enableDetailedErrors)
                {
                    var exception = error.InnerException ?? error;
                    hubResult.StackTrace = _isDebuggingEnabled ? exception.StackTrace : null;
                    hubResult.Error      = exception.Message;
                }
                else
                {
                    hubResult.Error = String.Format(CultureInfo.CurrentCulture, Resources.Error_HubInvocationFailed, request.Hub, request.Method);
                }
            }

            return(Transport.Send(hubResult));
        }
Exemplo n.º 4
0
        private Task ProcessResponse(StateChangeTracker tracker, 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)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                _counters.ErrorsAllTotal.Increment();
                _counters.ErrorsAllPerSec.Increment();
            }

            var hubResult = new HubResponse
            {
                State      = tracker.GetChanges(),
                Result     = result,
                Id         = request.Id,
                Error      = errorMessage,
                StackTrace = stackTrace
            };

            return(Transport.Send(hubResult));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Processes the hub's incoming method calls.
        /// </summary>
        protected override Task OnReceived(IRequest 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));
        }
Exemplo n.º 6
0
 public HubInvokerContext(IHub hub, StateChangeTracker tracker, MethodDescriptor methodDescriptor, IList <object> args)
 {
     Hub = hub;
     MethodDescriptor = methodDescriptor;
     Args             = args;
     StateTracker     = tracker;
 }
        /// <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="tracker">The connection hub state.</param>
        public HubConnectionContext(IHubPipelineInvoker pipelineInvoker, IConnection connection, string hubName, string connectionId, StateChangeTracker tracker)
            : base(connection, pipelineInvoker, hubName)
        {
            _connectionId = connectionId;

            Caller = new StatefulSignalProxy(connection, pipelineInvoker, connectionId, PrefixHelper.HubConnectionIdPrefix, hubName, tracker);
            All = AllExcept();
            Others = AllExcept(connectionId);
        }
Exemplo n.º 8
0
        private Task InvokeHubPipeline(IHub hub,
                                       IJsonValue[] parameterValues,
                                       MethodDescriptor methodDescriptor,
                                       HubRequest hubRequest,
                                       StateChangeTracker tracker)
        {
            // TODO: Make adding parameters here pluggable? IValueProvider? ;)
            HubInvocationProgress progress = GetProgressInstance(methodDescriptor, value => SendProgressUpdate(hub.Context.ConnectionId, tracker, value, hubRequest));

            Task <object> piplineInvocation;

            try
            {
                var args = _binder.ResolveMethodParameters(methodDescriptor, parameterValues);

                // We need to add the IProgress<T> instance after resolving the method as the resolution
                // itself looks for overload matches based on the incoming arg values
                if (progress != null)
                {
                    args = args.Concat(new [] { progress }).ToList();
                }

                var context = new HubInvokerContext(hub, tracker, methodDescriptor, args);

                // Invoke the pipeline and save the task
                piplineInvocation = _pipelineInvoker.Invoke(context);
            }
            catch (Exception ex)
            {
                piplineInvocation = TaskAsyncHelper.FromError <object>(ex);
            }

            // Determine if we have a faulted task or not and handle it appropriately.
            return(piplineInvocation.ContinueWithPreservedCulture(task =>
            {
                if (progress != null)
                {
                    // Stop ability to send any more progress updates
                    progress.SetComplete();
                }

                if (task.IsFaulted)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: task.Exception);
                }
                else if (task.IsCanceled)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: new OperationCanceledException());
                }
                else
                {
                    return ProcessResponse(tracker, task.Result, hubRequest, error: null);
                }
            })
                   .FastUnwrap());
        }
Exemplo n.º 9
0
        /// <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="tracker">The connection hub state.</param>
        public HubConnectionContext(IHubPipelineInvoker pipelineInvoker, IConnection connection, string hubName, string connectionId, StateChangeTracker tracker)
        {
            _send = (signal, invocation, exclude) => pipelineInvoker.Send(new HubOutgoingInvokerContext(connection, signal, invocation, exclude));
            _connectionId = connectionId;
            _hubName = hubName;

            Caller = new StatefulSignalProxy(_send, connectionId, PrefixHelper.HubConnectionIdPrefix, hubName, tracker);
            All = AllExcept();
            Others = AllExcept(connectionId);
        }
Exemplo n.º 10
0
        private Task SendProgressUpdate(string connectionId, StateChangeTracker tracker, object value, HubRequest request)
        {
            var hubResult = new HubResponse
            {
                State    = tracker.GetChanges(),
                Progress = new { I = request.Id, D = value },
                // We prefix the ID here to ensure old clients treat this as a hub response
                // but fail to lookup a corresponding callback and thus no-op
                Id = "P|" + request.Id,
            };

            return(Connection.Send(connectionId, hubResult));
        }
Exemplo n.º 11
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();

                // 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.
                methodDescriptor = new MethodDescriptor
                {
                    Invoker = (emptyHub, emptyParameters) =>
                    {
                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.Error_MethodCouldNotBeResolved, hubRequest.Method));
                    },
                    Attributes = new List <Attribute>(),
                    Parameters = new List <ParameterDescriptor>()
                };
            }

            // 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)
                   .ContinueWith(task => hub.Dispose(), TaskContinuationOptions.ExecuteSynchronously));
        }
Exemplo n.º 12
0
        public TestableLoadHub()
        {
            const string connectionId = "1234";
            const string hubName = "LoadHub";
            var resolver = new DefaultDependencyResolver();
            Config = resolver.Resolve<IConfigurationManager>();

            var mockConnection = new Mock<IConnection>();
            var mockUser = new Mock<IPrincipal>();
            var mockHubPipelineInvoker = new Mock<IHubPipelineInvoker>();

            var mockRequest = new Mock<IRequest>();
            mockRequest.Setup(r => r.User).Returns(mockUser.Object);

            var tracker = new StateChangeTracker();

            Clients = new HubConnectionContext(mockHubPipelineInvoker.Object, mockConnection.Object, hubName, connectionId, tracker);
            Context = new HubCallerContext(mockRequest.Object, connectionId);
        }
Exemplo n.º 13
0
        private Task ProcessResponse(StateChangeTracker tracker, object result, HubRequest request, Exception error)
        {
            var hubResult = new HubResponse
            {
                State  = tracker.GetChanges(),
                Result = result,
                Id     = request.Id,
            };

            if (error != null)
            {
                _counters.ErrorsHubInvocationTotal.Increment();
                _counters.ErrorsHubInvocationPerSec.Increment();
                _counters.ErrorsAllTotal.Increment();
                _counters.ErrorsAllPerSec.Increment();

                var hubError = error.InnerException as HubException;

                if (_enableDetailedErrors || hubError != null)
                {
                    var exception = error.InnerException ?? error;
                    hubResult.StackTrace = _isDebuggingEnabled ? exception.StackTrace : null;
                    hubResult.Error      = exception.Message;

                    if (hubError != null)
                    {
                        hubResult.IsHubException = true;
                        hubResult.ErrorData      = hubError.ErrorData;
                    }
                }
                else
                {
                    hubResult.Error = String.Format(CultureInfo.CurrentCulture, Resources.Error_HubInvocationFailed, request.Hub, request.Method);
                }
            }

            Trace.TraceVerbose("Sending hub invocation result to connection {0} using transport {1}", Transport.ConnectionId, Transport.GetType().Name);

            return(Transport.Send(hubResult));
        }
Exemplo n.º 14
0
            public void CanDeserializeClientState()
            {
                var clientState = new StateChangeTracker();
                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);
            }
Exemplo n.º 15
0
        private Task InvokeHubPipeline(IHub hub,
                                       IJsonValue[] parameterValues,
                                       MethodDescriptor methodDescriptor,
                                       HubRequest hubRequest,
                                       StateChangeTracker tracker)
        {
            Task <object> piplineInvocation;

            try
            {
                var args    = _binder.ResolveMethodParameters(methodDescriptor, parameterValues);
                var context = new HubInvokerContext(hub, tracker, methodDescriptor, args);

                // Invoke the pipeline and save the task
                piplineInvocation = _pipelineInvoker.Invoke(context);
            }
            catch (Exception ex)
            {
                piplineInvocation = TaskAsyncHelper.FromError <object>(ex);
            }

            // Determine if we have a faulted task or not and handle it appropriately.
            return(piplineInvocation.ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: task.Exception);
                }
                else if (task.IsCanceled)
                {
                    return ProcessResponse(tracker, result: null, request: hubRequest, error: new OperationCanceledException());
                }
                else
                {
                    return ProcessResponse(tracker, task.Result, hubRequest, error: null);
                }
            })
                   .FastUnwrap());
        }
Exemplo n.º 16
0
 public StatefulSignalProxy(IConnection connection, IHubPipelineInvoker invoker, string signal, string hubName, string prefix, StateChangeTracker tracker)
     : base(connection, invoker, signal, prefix, hubName, ListHelper <string> .Empty)
 {
     _tracker = tracker;
 }
Exemplo n.º 17
0
        private IHub CreateHub(IRequest request, HubDescriptor descriptor, string connectionId, StateChangeTracker tracker = null, bool throwIfFailedToCreate = false)
        {
            try
            {
                var hub = _manager.ResolveHub(descriptor.Name);

                if (hub != null)
                {
                    tracker = tracker ?? new StateChangeTracker();

                    hub.Context = new HubCallerContext(request, connectionId);
                    hub.Clients = new HubConnectionContext(_pipelineInvoker, Connection, descriptor.Name, connectionId, tracker);
                    hub.Groups  = new GroupManager(Connection, PrefixHelper.GetHubGroupName(descriptor.Name));
                }

                return(hub);
            }
            catch (Exception ex)
            {
                Trace.TraceInformation(String.Format(CultureInfo.CurrentCulture, Resources.Error_ErrorCreatingHub + ex.Message, descriptor.Name));

                if (throwIfFailedToCreate)
                {
                    throw;
                }

                return(null);
            }
        }
Exemplo n.º 18
0
            public void MissingUsernameReturnsFalse()
            {
                var clientState = new StateChangeTracker();
                string clientId = "1";
                var user = new ChatUser();

                TestableChat chat = GetTestableChat(clientId, clientState, user);

                bool result = chat.Join();

                Assert.False(result);
            }
Exemplo n.º 19
0
 public static TestableChat GetTestableChat(string clientId, StateChangeTracker clientState, ChatUser user)
 {
     return GetTestableChat(clientId, clientState, user, new NameValueCollection());
 }
Exemplo n.º 20
0
 public static TestableChat GetTestableChat(string clientId, StateChangeTracker clientState, ChatUser user)
 {
     return GetTestableChat(clientId, clientState, user, new Dictionary<string, Cookie>());
 }
 public StatefulSignalProxy(IConnection connection, IHubPipelineInvoker invoker, string signal, string hubName, string prefix, StateChangeTracker tracker)
     : base(connection, invoker, signal, prefix, hubName, ListHelper<string>.Empty)
 {
     _tracker = tracker;
 }
Exemplo n.º 22
0
        /// <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="tracker">The connection hub state.</param>
        public HubConnectionContext(IHubPipelineInvoker pipelineInvoker, IConnection connection, string hubName, string connectionId, StateChangeTracker tracker)
        {
            _send         = (signal, invocation, exclude) => pipelineInvoker.Send(new HubOutgoingInvokerContext(connection, signal, invocation, exclude));
            _connectionId = connectionId;
            _hubName      = hubName;

            Caller = new StatefulSignalProxy(_send, connectionId, PrefixHelper.HubConnectionIdPrefix, hubName, tracker);
            All    = AllExcept();
            Others = AllExcept(connectionId);
        }
Exemplo n.º 23
0
 public StatefulSignalProxy(Func<string, ClientHubInvocation, IList<string>, Task> send, string signal, string hubName, string prefix, StateChangeTracker tracker)
     : base(send, signal, prefix, hubName, ListHelper<string>.Empty)
 {
     _tracker = tracker;
 }
Exemplo n.º 24
0
            public void CannotJoinChat()
            {
                var clientState = new StateChangeTracker();
                string clientId = "1";
                var user = new ChatUser
                {
                    Id = "1234",
                    Name = "John"
                };

                TestableChat chat = GetTestableChat(clientId, clientState, user);
                chat.Clients.Caller.id = "1234";

                bool result = chat.Join();

                Assert.False(result);
            }
Exemplo n.º 25
0
        /// <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="tracker">The connection hub state.</param>
        public HubConnectionContext(IHubPipelineInvoker pipelineInvoker, IConnection connection, string hubName, string connectionId, StateChangeTracker tracker)
            : base(connection, pipelineInvoker, hubName)
        {
            _connectionId = connectionId;

            Caller      = new StatefulSignalProxy(connection, pipelineInvoker, connectionId, PrefixHelper.HubConnectionIdPrefix, hubName, tracker);
            CallerState = new CallerStateProxy(tracker);
            All         = AllExcept();
            Others      = AllExcept(connectionId);
        }
Exemplo n.º 26
0
 public StatefulSignalProxy(Func <string, ClientHubInvocation, IEnumerable <string>, Task> send, string signal, string hubName, StateChangeTracker tracker)
     : base(send, signal, hubName)
 {
     _tracker = tracker;
 }
Exemplo n.º 27
0
 public CallerStateProxy(StateChangeTracker tracker)
 {
     _tracker = tracker;
 }
Exemplo n.º 28
0
 public CallerStateProxy(StateChangeTracker tracker)
 {
     _tracker = tracker;
 }
Exemplo n.º 29
0
            public void CanJoinChatIfIdentitySet()
            {
                var clientState = new StateChangeTracker();
                string clientId = "1";
                var user = new ChatUser
                {
                    Id = "1234",
                    Name = "John",
                    Identity = "foo"
                };

                TestableChat chat = GetTestableChat(clientId, clientState, user);
                chat.Clients.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);
            }
Exemplo n.º 30
0
 public StatefulSignalProxy(Func <string, ClientHubInvocation, IList <string>, Task> send, string signal, string hubName, string prefix, StateChangeTracker tracker)
     : base(send, signal, prefix, hubName, ListHelper <string> .Empty)
 {
     _tracker = tracker;
 }
Exemplo n.º 31
0
        private TestableLobby GetHub( string connectionId,
                                      StateChangeTracker clientState  = null,
                                      IDictionary<string, Cookie> cookies = null,
                                      Mock<IGroupManager> groupManager = null,
                                      Mock<IGameHandler> gameHandler = null,
                                      Mock<IRegistrationHandler> registrationHandler = null,
                                      Mock<IUserHandler> userHandler = null,
                                      Mock<IMappingHandler> mappingHandler = null,
                                      Mock<IScenarioHandler> scenarioHandler = null )
        {
            clientState = clientState ?? new StateChangeTracker();
            cookies = cookies ?? new Dictionary<string, Cookie>();

            var lobby = new TestableLobby( gameHandler ?? new Mock<IGameHandler>(),
                                           registrationHandler ?? new Mock<IRegistrationHandler>(),
                                           userHandler ?? new Mock<IUserHandler>(),
                                           mappingHandler ?? new Mock<IMappingHandler>(),
                                           scenarioHandler ?? new Mock<IScenarioHandler>() );

            lobby.Clients = new HubConnectionContext( new Mock<IHubPipelineInvoker>().Object,
                                                      new Mock<IConnection>().Object,
                                                      "Lobby",
                                                      connectionId,
                                                      clientState );

            var request = new Mock<IRequest>();
            request.Setup( a => a.Cookies ).Returns( cookies );

            lobby.Context = new HubCallerContext( request.Object, connectionId );
            lobby.Groups = ( groupManager ?? new Mock<IGroupManager>() ).Object;

            return lobby;
        }