public async Task TransportTimesOutIfNoInitMessage(HostType hostType, TransportType transportType, MessageBusType messageBusType) { var mre = new AsyncManualResetEvent(); using (var host = CreateHost(hostType, transportType)) { host.Initialize(transportConnectTimeout: 1, messageBusType: messageBusType); HubConnection hubConnection = CreateHubConnection(host, "/no-init"); IHubProxy proxy = hubConnection.CreateHubProxy("DelayedOnConnectedHub"); using (hubConnection) { try { await hubConnection.Start(host.Transport); } catch { mre.Set(); } Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public async Task SuccessiveTimeoutTest(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new AsyncManualResetEvent(false); host.Initialize(keepAlive: 5, messageBusType: messageBusType); var connection = CreateConnection(host, "/my-reconnect"); using (connection) { connection.Reconnected += () => { mre.Set(); }; await connection.Start(host.Transport); ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromMilliseconds(300)); // Assert that Reconnected is called Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(15))); // Assert that Reconnected is called again mre.Reset(); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(15))); // Clean-up mre.Dispose(); } } }
public async Task DateAsStringRoundtrip() { var serializer = new JsonSerializer(); serializer.DateParseHandling = DateParseHandling.None; string expected = "1960-08-25T00:00:00"; TypeWithDateAsString callback = null; using (var host = CreateHost(HostType.Memory, TransportType.Auto)) { host.Initialize(); host.Resolver.Register(typeof(JsonSerializer), () => serializer); var connection = CreateHubConnection(host); connection.JsonSerializer.DateParseHandling = DateParseHandling.None; var hub = connection.CreateHubProxy("DateAsStringHub"); var request = new TypeWithDateAsString(); request.DateAsString = expected; var wh = new AsyncManualResetEvent(false); hub.On<TypeWithDateAsString>("Callback", (data) => { callback = data; wh.Set(); }); await connection.Start(host.Transport); var response = await hub.Invoke<TypeWithDateAsString>("Invoke", request); Assert.Equal(expected, response.DateAsString); Assert.True(await wh.WaitAsync(TimeSpan.FromSeconds(10))); Assert.Equal(expected, callback.DateAsString); } }
public async Task ReconnectionSuccesfulTest(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new AsyncManualResetEvent(false); host.Initialize(keepAlive: null, messageBusType: messageBusType); var connection = CreateConnection(host, "/my-reconnect"); if (transportType == TransportType.LongPolling) { ((Client.Transports.LongPollingTransport)host.Transport).ReconnectDelay = TimeSpan.Zero; } using (connection) { ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromSeconds(2)); connection.Reconnected += () => { mre.Set(); }; await connection.Start(host.Transport); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); // Clean-up mre.Dispose(); } } }
public async Task ReconnectFiresAfterHostShutdown(TransportType transportType, MessageBusType messageBusType) { var serverRestarts = 0; var serverReconnects = 0; var host = new ServerRestarter(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; UseMessageBus(messageBusType, config.Resolver); app.MapSignalR<MyReconnect>("/endpoint", config); serverRestarts++; serverReconnects = 0; config.Resolver.Register(typeof(MyReconnect), () => new MyReconnect(() => serverReconnects++)); }); using (host) { using (var connection = CreateConnection("http://foo/endpoint")) { var transport = CreateTransport(transportType, host); var pollEvent = new AsyncManualResetEvent(); var reconnectedEvent = new AsyncManualResetEvent(); host.OnPoll = () => { pollEvent.Set(); }; connection.Reconnected += () => { reconnectedEvent.Set(); }; await connection.Start(transport); // Wait for the /poll before restarting the server Assert.True(await pollEvent.WaitAsync(TimeSpan.FromSeconds(15)), "Timed out waiting for poll request"); host.Restart(); Assert.True(await reconnectedEvent.WaitAsync(TimeSpan.FromSeconds(15)), "Timed out waiting for client side reconnect"); Assert.Equal(2, serverRestarts); Assert.Equal(1, serverReconnects); } } }
public async Task SendToUserConnectDisconnectEvents() { using (var host = CreateHost(HostType.IISExpress)) { host.Initialize(); var connection1 = CreateAuthHubConnection(host, "user1", "password"); var connection2 = CreateAuthHubConnection(host, "user2", "password"); int connected = 0; int disconnected = 0; var wh1 = new AsyncManualResetEvent(); var wh2 = new AsyncManualResetEvent(); var hub1 = connection1.CreateHubProxy("AuthenticatedEchoHub"); var hub2 = connection2.CreateHubProxy("AuthenticatedEchoHub"); hub1.On<string>("SendUserOnConnected", (user) => { if (++connected >= 2) { wh1.Set(); } }); hub1.On<string>("SendUserOnDisconnected", (user) => { if (++disconnected >= 1) { wh2.Set(); } }); using (connection1) { using (connection2) { await connection1.Start(); await connection2.Start(new Microsoft.AspNet.SignalR.Client.Transports.WebSocketTransport()); Assert.True(await wh1.WaitAsync(TimeSpan.FromSeconds(5))); } Assert.True(await wh2.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task SendToGroupsFromOutsideOfConnection() { using (var host = new MemoryHost()) { IPersistentConnectionContext connectionContext = null; host.Configure(app => { var configuration = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR<BroadcastConnection>("/echo", configuration); connectionContext = configuration.Resolver.Resolve<IConnectionManager>().GetConnectionContext<BroadcastConnection>(); }); var connection1 = new Client.Connection("http://foo/echo"); using (connection1) { var wh1 = new AsyncManualResetEvent(initialState: false); await connection1.Start(host); connection1.Received += data => { Assert.Equal("yay", data); wh1.Set(); }; connectionContext.Groups.Add(connection1.ConnectionId, "Foo").Wait(); var ignore = connectionContext.Groups.Send(new[] { "Foo", "Bar" }, "yay"); Assert.True(await wh1.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public async Task OnConnectionSlowTest(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new AsyncManualResetEvent(false); host.Initialize(keepAlive: null, messageBusType: messageBusType); var connection = CreateConnection(host, "/my-reconnect"); using (connection) { ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromSeconds(21), TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(5)); connection.ConnectionSlow += () => { mre.Set(); }; await connection.Start(host.Transport); // Assert Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(15))); // Clean-up mre.Dispose(); } } }
public async Task ConnectionErrorCapturesExceptionsThrownInClientHubMethod(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { var wh = new AsyncManualResetEvent(); Exception thrown = new Exception(), caught = null; host.Initialize(messageBusType: messageBusType); var connection = CreateHubConnection(host); using (connection) { var proxy = connection.CreateHubProxy("ChatHub"); proxy.On<string>("addMessage", (message) => { throw thrown; }); connection.Error += e => { caught = e; wh.Set(); }; await connection.Start(host.Transport); var ignore = proxy.Invoke("Send", "").Catch(); Assert.True(await wh.WaitAsync(TimeSpan.FromSeconds(5))); Assert.Equal(thrown, caught); } } }
public async Task FarmGroupAddCompletesSuccessfully(TransportType transportType) { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers const int nodeCount = 2; var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); // Ensure /send and /connect requests get handled by different servers Func<string, int> scheduler = url => url.Contains("/send") ? 0 : 1; using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount, scheduler)) { loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On<string>("message", m => { if (m == message) { mre.Set(); } }); Client.Transports.IClientTransport transport; switch (transportType) { case TransportType.LongPolling: transport = new Client.Transports.LongPollingTransport(loadBalancer); break; case TransportType.ServerSentEvents: transport = new Client.Transports.ServerSentEventsTransport(loadBalancer); break; default: throw new ArgumentException("transportType"); } await connection.Start(transport); await proxy.Invoke("JoinGroup", group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task GroupsWorkAfterServerRestart() { var host = new ServerRestarter(app => { var config = new HubConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR(config); }); using (host) { using (var connection = CreateHubConnection("http://foo/")) { var reconnectedEvent = new AsyncManualResetEvent(); connection.Reconnected += reconnectedEvent.Set; var hubProxy = connection.CreateHubProxy("groupChat"); var sendEvent = new AsyncManualResetEvent(); string sendMessage = null; hubProxy.On<string>("send", message => { sendMessage = message; sendEvent.Set(); }); var groupName = "group$&+,/:;=?@[]1"; var groupMessage = "hello"; // MemoryHost doesn't support WebSockets, and it is difficult to ensure that // the reconnected event is reliably fired with the LongPollingTransport. await connection.Start(new ServerSentEventsTransport(host)); await hubProxy.Invoke("Join", groupName); host.Restart(); Assert.True(await reconnectedEvent.WaitAsync(TimeSpan.FromSeconds(15)), "Timed out waiting for client side reconnect."); await hubProxy.Invoke("Send", groupName, groupMessage); Assert.True(await sendEvent.WaitAsync(TimeSpan.FromSeconds(15)), "Timed out waiting for message."); Assert.Equal(groupMessage, sendMessage); } } }
public async Task ClientStaysReconnectedAfterDisconnectTimeout(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(keepAlive: null, connectionTimeout: 2, disconnectTimeout: 8, // 8s because the default heartbeat time span is 5s messageBusType: messageBusType); var connection = CreateHubConnection(host, "/force-lp-reconnect"); using (connection) { var reconnectingWh = new AsyncManualResetEvent(); var reconnectedWh = new AsyncManualResetEvent(); connection.Reconnecting += () => { reconnectingWh.Set(); Assert.Equal(ConnectionState.Reconnecting, connection.State); }; connection.Reconnected += () => { reconnectedWh.Set(); Assert.Equal(ConnectionState.Connected, connection.State); }; await connection.Start(host.Transport); // Force reconnect await Task.Delay(TimeSpan.FromSeconds(5)); Assert.True(await reconnectingWh.WaitAsync(TimeSpan.FromSeconds(30))); Assert.True(await reconnectedWh.WaitAsync(TimeSpan.FromSeconds(30))); await Task.Delay(TimeSpan.FromSeconds(15)); Assert.NotEqual(ConnectionState.Disconnected, connection.State); } } }
public async Task ConnectionErrorCapturesExceptionsThrownWhenReceivingResponseFromSend() { using (var host = new MemoryHost()) { host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR<TransportResponse>("/transport-response", config); }); var transports = new List<IClientTransport>() { new ServerSentEventsTransport(host), new LongPollingTransport(host) }; foreach (var transport in transports) { Debug.WriteLine("Transport: {0}", (object)transport.Name); var wh = new AsyncManualResetEvent(); Exception thrown = new InvalidOperationException(), caught = null; var connection = new Connection("http://foo/transport-response"); using (connection) { connection.Received += data => { throw thrown; }; connection.Error += e => { caught = e; wh.Set(); }; await connection.Start(transport); var ignore = connection.Send(""); Assert.True(await wh.WaitAsync(TimeSpan.FromSeconds(5))); Assert.Equal(thrown, caught); } } } }
public async Task RequestHeadersCanBeSetOnceConnected(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { // Arrange host.Initialize(); var connection = CreateConnection(host, "/examine-request"); var mre = new AsyncManualResetEvent(); using (connection) { connection.Received += arg => { JObject headers = JsonConvert.DeserializeObject<JObject>(arg); Assert.Equal("test-header", (string)headers["testHeader"]); mre.Set(); }; await connection.Start(host.Transport); connection.Headers.Add("test-header", "test-header"); var ignore = connection.Send("message"); // Assert Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public async Task PrefixMatchingIsNotGreedyExactMatch() { using (var host = new MemoryHost()) { host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR<MyConnection>("/echo", config); app.MapSignalR<MyConnection2>("/echo2", config); }); var tcs = new TaskCompletionSource<string>(); var mre = new AsyncManualResetEvent(); var connection = new Connection("http://foo/echo"); using (connection) { connection.Received += data => { tcs.TrySetResult(data); mre.Set(); }; await connection.Start(host); var ignore = connection.Send(""); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); Assert.Equal("MyConnection", tcs.Task.Result); } } }
public async Task WaitingOnHubInvocationDoesNotDeadlock(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); HubConnection hubConnection = CreateHubConnection(host); var mre = new AsyncManualResetEvent(); using (hubConnection) { IHubProxy proxy = hubConnection.CreateHubProxy("EchoHub"); int callbackInvokedCount = 0; proxy.On<string>("echo", message => { callbackInvokedCount++; if (callbackInvokedCount == 4) { mre.Set(); } else { proxy.Invoke("EchoCallback", message); } }); await hubConnection.Start(host.Transport); var ignore = proxy.Invoke("EchoCallback", "message").Catch(); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public async Task ClientCallbackArgumentTypeMismatchExceptionThrown(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); HubConnection hubConnection = CreateHubConnection(host); var tcs = new TaskCompletionSource<Exception>(); var mre = new AsyncManualResetEvent(); hubConnection.Error += (ex) => { tcs.TrySetResult(ex); mre.Set(); }; using (hubConnection) { IHubProxy proxy = hubConnection.CreateHubProxy("ClientCallbackHub"); proxy.On<int>("foo", args => { }); await hubConnection.Start(host.Transport); await proxy.Invoke("SendArgumentsTypeMismatch"); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); Assert.IsType(typeof(InvalidOperationException), tcs.Task.Result); Assert.Equal(((InvalidOperationException)tcs.Task.Result).Message, "A client callback for event foo with 1 argument(s) was found, however an error occurred because Could not convert string to integer: arg1. Path ''."); } } }
public async Task ClientCallbackWithFewerArgumentsDoesNotThrow(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); HubConnection hubConnection = CreateHubConnection(host); var mre = new AsyncManualResetEvent(); var wh = new AsyncManualResetEvent(); hubConnection.Error += (ex) => { wh.Set(); }; using (hubConnection) { IHubProxy proxy = hubConnection.CreateHubProxy("ClientCallbackHub"); proxy.On("twoArgsMethod", () => { mre.Set(); }); await hubConnection.Start(host.Transport); await proxy.Invoke("SendOneArgument"); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); Assert.False(await wh.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task ClientCallbackInvalidNumberOfArgumentsExceptionThrown(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); HubConnection hubConnection = CreateHubConnection(host); var tcs = new TaskCompletionSource<Exception>(); var mre = new AsyncManualResetEvent(); hubConnection.Error += (ex) => { tcs.TrySetResult(ex); mre.Set(); }; using (hubConnection) { IHubProxy proxy = hubConnection.CreateHubProxy("ClientCallbackHub"); proxy.On<string, string>("twoArgsMethod", (arg1, arg2) => { }); await hubConnection.Start(host.Transport); await proxy.Invoke("SendOneArgument"); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); Assert.IsType(typeof(InvalidOperationException), tcs.Task.Result); Assert.Equal(((InvalidOperationException)tcs.Task.Result).Message, "A client callback for event twoArgsMethod with 1 argument(s) could not be found"); } } }
public async Task RequestHeadersCanBeSetOnceConnected(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange host.Initialize(messageBusType: messageBusType); HubConnection hubConnection = CreateHubConnection(host); var mre = new AsyncManualResetEvent(); using (hubConnection) { IHubProxy proxy = hubConnection.CreateHubProxy("ExamineHeadersHub"); proxy.On("sendHeader", headers => { Assert.Equal("test-header", (string)headers.testHeader); mre.Set(); }); await hubConnection.Start(host.Transport); hubConnection.Headers.Add("test-header", "test-header"); var ignore = proxy.Invoke("Send").Catch(); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task ReconnectRequestPathEndsInReconnect(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var tcs = new TaskCompletionSource<bool>(); var mre = new AsyncManualResetEvent(); var receivedMessage = false; host.Initialize(keepAlive: null, connectionTimeout: 2, disconnectTimeout: 6); using (var connection = CreateConnection(host, "/force-lp-reconnect/examine-reconnect")) { connection.Received += reconnectEndsPath => { if (!receivedMessage) { tcs.TrySetResult(reconnectEndsPath == "True"); receivedMessage = true; mre.Set(); } }; await connection.Start(host.Transport); // Wait for reconnect Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); Assert.True(tcs.Task.Result); } } }
public async Task BasicAuthCredentialsFlow(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = CreateConnection(host, "/basicauth/echo"); var tcs = new TaskCompletionSource<string>(); var mre = new AsyncManualResetEvent(); using (connection) { connection.Credentials = new System.Net.NetworkCredential("user", "password"); connection.Received += data => { tcs.TrySetResult(data); mre.Set(); }; await connection.Start(host.Transport); connection.SendWithTimeout("Hello World"); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(10))); Assert.Equal("Hello World", tcs.Task.Result); } } }
public async Task ClientStopsReconnectingAfterDisconnectTimeout(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(disconnectTimeout: 6, messageBusType: messageBusType); var connection = CreateHubConnection(host); using (connection) { var reconnectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); connection.Reconnecting += () => { reconnectWh.Set(); Assert.Equal(ConnectionState.Reconnecting, connection.State); }; connection.Closed += () => { disconnectWh.Set(); Assert.Equal(ConnectionState.Disconnected, connection.State); }; await connection.Start(host.Transport); host.Shutdown(); Assert.True(await reconnectWh.WaitAsync(TimeSpan.FromSeconds(25)), "Reconnect never fired"); Assert.True(await disconnectWh.WaitAsync(TimeSpan.FromSeconds(25)), "Closed never fired"); } } }
// [InlineData(HostType.Memory, TransportType.LongPolling)] // [InlineData(HostType.IISExpress, TransportType.Auto)] public async Task GroupCanBeAddedAndMessagedOnConnected(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { var wh = new AsyncManualResetEvent(); host.Initialize(messageBusType: messageBusType); var connection = CreateConnection(host, "/add-group"); using (connection) { connection.Received += data => { Assert.Equal("hey", data); wh.Set(); }; await connection.Start(host.Transport); connection.SendWithTimeout(""); Assert.True(await wh.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task ConnectionErrorCapturesExceptionsThrownInReceived(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { var errorsCaught = 0; var wh = new AsyncManualResetEvent(); Exception thrown = new Exception(), caught = null; host.Initialize(messageBusType: messageBusType); var connection = CreateConnection(host, "/multisend"); using (connection) { connection.Received += _ => { throw thrown; }; connection.Error += e => { caught = e; if (Interlocked.Increment(ref errorsCaught) == 2) { wh.Set(); } }; await connection.Start(host.Transport); Assert.True(await wh.WaitAsync(TimeSpan.FromSeconds(5))); Assert.Equal(thrown, caught); } } }
public async Task SendToAllButCaller(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(messageBusType: messageBusType); var connection1 = CreateConnection(host, "/filter"); var connection2 = CreateConnection(host, "/filter"); using (connection1) using (connection2) { var wh1 = new AsyncManualResetEvent(initialState: false); var wh2 = new AsyncManualResetEvent(initialState: false); connection1.Received += data => wh1.Set(); connection2.Received += data => wh2.Set(); await connection1.Start(host.TransportFactory()); await connection2.Start(host.TransportFactory()); connection1.SendWithTimeout("test"); Assert.False(await wh1.WaitAsync(TimeSpan.FromSeconds(5))); Assert.True(await wh2.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task ContextGroupAddCompletesSuccessfully() { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var memoryHost = new MemoryHost()) { memoryHost.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On<string>("message", m => { if (m == message) { mre.Set(); } }); await connection.Start(memoryHost); // Add the connection to a group via an IHubContext on a "second" server. var secondResolver = new DefaultDependencyResolver(); secondResolver.Register(typeof(IMessageBus), () => bus); var secondConnectionManager = secondResolver.Resolve<IConnectionManager>(); var secondHubContext = secondConnectionManager.GetHubContext<FarmGroupHub>(); await secondHubContext.Groups.Add(connection.ConnectionId, group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task ReceivePreserializedJson(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(messageBusType: messageBusType); var connection = CreateConnection(host, "/preserialize"); var tcs = new TaskCompletionSource<string>(); var mre = new AsyncManualResetEvent(); connection.Received += json => { tcs.TrySetResult(json); mre.Set(); }; using (connection) { await connection.Start(host.Transport); connection.SendWithTimeout(new { preserialized = true }); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); var json = JObject.Parse(tcs.Task.Result); Assert.True((bool)json["preserialized"]); } } }
public async Task SendToGroupsFromOutsideOfHub() { using (var host = new MemoryHost()) { IHubContext<IBasicClient> hubContext = null; host.Configure(app => { var configuration = new HubConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR(configuration); hubContext = configuration.Resolver.Resolve<IConnectionManager>().GetHubContext<SendToSome, IBasicClient>(); }); var connection1 = new HubConnection("http://foo/"); using (connection1) { var wh1 = new AsyncManualResetEvent(initialState: false); var hub1 = connection1.CreateHubProxy("SendToSome"); await connection1.Start(host); hub1.On("send", () => wh1.Set()); await hubContext.Groups.Add(connection1.ConnectionId, "Foo"); hubContext.Clients.Groups(new[] { "Foo" }).send(); Assert.True(await wh1.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public async Task GroupsTokenIsPerConnectionId() { using (var host = new MemoryHost()) { IProtectedData protectedData = null; host.Configure(app => { var config = new HubConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR<MyGroupConnection>("/echo", config); protectedData = config.Resolver.Resolve<IProtectedData>(); }); var connection = new Client.Connection("http://memoryhost/echo"); using (connection) { var inGroup = new AsyncManualResetEvent(); connection.Received += data => { if (data == "group") { inGroup.Set(); } }; await connection.Start(host); await inGroup.WaitAsync(TimeSpan.FromSeconds(10)); Assert.NotNull(connection.GroupsToken); var spyWh = new AsyncManualResetEvent(); var hackerConnection = new Client.Connection(connection.Url) { ConnectionId = "hacker" }; var url = GetUrl(protectedData, connection, connection.GroupsToken); var response = await host.Get(url, r => { }, isLongRunning: true); var reader = new EventSourceStreamReader(hackerConnection, response.GetStream()); reader.Message = sseEvent => { if (sseEvent.EventType == EventType.Data && sseEvent.Data != "initialized" && sseEvent.Data != "{}") { spyWh.Set(); } }; reader.Start(); await connection.Send("random"); Assert.False(await spyWh.WaitAsync(TimeSpan.FromSeconds(5))); } } }