public async Task DisconnectFiresForPersistentConnectionWhenClientDisconnects() { using (var host = new MemoryHost()) { var connectWh = new TaskCompletionSource <object>(); var disconnectWh = new TaskCompletionSource <object>(); var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = dr }; app.MapSignalR <MyConnection>("/echo", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); }); var connection = new Client.Connection("http://foo/echo"); await connection.Start(host); await connectWh.Task.OrTimeout(TimeSpan.FromSeconds(10)); ((Client.IConnection)connection).Disconnect(); await disconnectWh.Task.OrTimeout(TimeSpan.FromSeconds(20)); } }
public void SendToAllButCaller() { using (var host = new MemoryHost()) { host.MapConnection <FilteredConnection>("/filter"); var connection1 = new Client.Connection("http://foo/filter"); var connection2 = new Client.Connection("http://foo/filter"); var wh1 = new ManualResetEventSlim(initialState: false); var wh2 = new ManualResetEventSlim(initialState: false); connection1.Received += data => wh1.Set(); connection2.Received += data => wh2.Set(); connection1.Start(host).Wait(); connection2.Start(host).Wait(); connection1.Send("test").Wait(); Assert.False(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); connection1.Stop(); connection2.Stop(); } }
public void GroupsReceiveMessages(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/groups"); var list = new List<string>(); connection.Received += data => { list.Add(data); }; connection.Start(host.Transport).Wait(); // Join the group connection.SendWithTimeout(new { type = 1, group = "test" }); // Sent a message connection.SendWithTimeout(new { type = 3, group = "test", message = "hello to group test" }); // Leave the group connection.SendWithTimeout(new { type = 2, group = "test" }); // Send a message connection.SendWithTimeout(new { type = 3, group = "test", message = "goodbye to group test" }); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(1, list.Count); Assert.Equal("hello to group test", list[0]); } }
public void GroupsReceiveMessages(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/groups"); var list = new List <string>(); connection.Received += data => { list.Add(data); }; connection.Start(host.Transport).Wait(); // Join the group connection.SendWithTimeout(new { type = 1, group = "test" }); // Sent a message connection.SendWithTimeout(new { type = 3, group = "test", message = "hello to group test" }); // Leave the group connection.SendWithTimeout(new { type = 2, group = "test" }); // Send a message connection.SendWithTimeout(new { type = 3, group = "test", message = "goodbye to group test" }); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(1, list.Count); Assert.Equal("hello to group test", list[0]); } }
public void AsyncStartShouldFailIfTransportStartFails() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); var ex = new Exception(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())) .Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = connection.Protocol.ToString(), ConnectionId = "Something", DisconnectTimeout = 120 })); transport.Setup(m => m.Start(connection, null, It.IsAny <CancellationToken>())) .Returns(TaskAsyncHelper.Delay(TimeSpan.FromMilliseconds(100)).Then(() => { throw ex; })); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); Assert.Equal(aggEx.Unwrap(), ex); Assert.Equal(ConnectionState.Disconnected, connection.State); }
public void CancelledStartShouldBeDisconnected() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())) .Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = connection.Protocol.ToString(), ConnectionId = "Something", DisconnectTimeout = 120 })); transport.Setup(m => m.Start(connection, null, It.IsAny <CancellationToken>())) .Returns(() => { var tcs = new TaskCompletionSource <object>(); tcs.SetCanceled(); return(tcs.Task); }); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(TaskCanceledException), ex); Assert.Equal(ConnectionState.Disconnected, connection.State); }
public void ReconnectDoesntFireAfterTimeOut(TransportType transportType, MessageBusType messageBusType) { using (var host = new MemoryHost()) { var conn = new MyReconnect(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; UseMessageBus(messageBusType, config.Resolver); app.MapSignalR <MyReconnect>("/endpoint", config); var configuration = config.Resolver.Resolve <IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.ConnectionTimeout = TimeSpan.FromSeconds(2); configuration.KeepAlive = null; config.Resolver.Register(typeof(MyReconnect), () => conn); }); var connection = new Client.Connection("http://foo/endpoint"); var transport = CreateTransport(transportType, host); connection.Start(transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(0, conn.Reconnects); } }
public void SendRaisesOnReceivedFromAllEvents() { using (var host = new MemoryHost()) { host.MapConnection <MySendingConnection>("/multisend"); var connection = new Client.Connection("http://foo/multisend"); var results = new List <string>(); connection.Received += data => { results.Add(data); }; connection.Start(host).Wait(); connection.Send("").Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); Assert.Equal("OnConnectedAsync1", results[0]); Assert.Equal("OnConnectedAsync2", results[1]); Assert.Equal("OnReceivedAsync1", results[2]); Assert.Equal("OnReceivedAsync2", results[3]); } }
public void SendRaisesOnReceivedFromAllEvents(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/multisend"); var results = new List <string>(); connection.Received += data => { results.Add(data); }; connection.Start(host.Transport).Wait(); connection.SendWithTimeout(""); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); Assert.Equal("OnConnectedAsync1", results[0]); Assert.Equal("OnConnectedAsync2", results[1]); Assert.Equal("OnReceivedAsync1", results[2]); Assert.Equal("OnReceivedAsync2", results[3]); } }
public void SendToAllButCaller(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection1 = new Client.Connection(host.Url + "/filter"); var connection2 = new Client.Connection(host.Url + "/filter"); var wh1 = new ManualResetEventSlim(initialState: false); var wh2 = new ManualResetEventSlim(initialState: false); connection1.Received += data => wh1.Set(); connection2.Received += data => wh2.Set(); connection1.Start(host.Transport).Wait(); connection2.Start(host.Transport).Wait(); connection1.SendWithTimeout("test"); Assert.False(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); connection1.Stop(); connection2.Stop(); } }
public void SendCanBeCalledAfterStateChangedEvent() { using (var host = new MemoryHost()) { host.MapConnection <MySendingConnection>("/multisend"); var connection = new Client.Connection("http://foo/multisend"); var results = new List <string>(); connection.Received += data => { results.Add(data); }; connection.StateChanged += stateChange => { if (stateChange.NewState == Client.ConnectionState.Connected) { connection.Send("").Wait(); } }; connection.Start(host).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); } }
// [InlineData(HostType.IIS, TransportType.LongPolling)] public void ThrownWebExceptionShouldBeUnwrapped(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/ErrorsAreFun"); // Expecting 404 var aggEx = Assert.Throws <AggregateException>(() => connection.Start(host.Transport).Wait()); connection.Stop(); using (var ser = aggEx.GetError()) { if (hostType == HostType.IISExpress) { Assert.Equal(System.Net.HttpStatusCode.InternalServerError, ser.StatusCode); } else { Assert.Equal(System.Net.HttpStatusCode.NotFound, ser.StatusCode); } Assert.NotNull(ser.ResponseBody); Assert.NotNull(ser.Exception); } } }
public void GroupsReceiveMessages() { using (var host = new MemoryHost()) { host.MapConnection <MyGroupConnection>("/groups"); var connection = new Client.Connection("http://foo/groups"); var list = new List <string>(); connection.Received += data => { list.Add(data); }; connection.Start(host).Wait(); // Join the group connection.Send(new { type = 1, group = "test" }).Wait(); // Sent a message connection.Send(new { type = 3, group = "test", message = "hello to group test" }).Wait(); // Leave the group connection.Send(new { type = 2, group = "test" }).Wait(); // Send a message connection.Send(new { type = 3, group = "test", message = "goodbye to group test" }).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(1, list.Count); Assert.Equal("hello to group test", list[0]); } }
public void ThrownWebExceptionShouldBeUnwrapped(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/ErrorsAreFun"); // Expecting 404 var aggEx = Assert.Throws<AggregateException>(() => connection.Start(host.Transport).Wait()); connection.Stop(); using (var ser = aggEx.GetError()) { if (hostType == HostType.IISExpress) { Assert.Equal(System.Net.HttpStatusCode.InternalServerError, ser.StatusCode); } else { Assert.Equal(System.Net.HttpStatusCode.NotFound, ser.StatusCode); } Assert.NotNull(ser.ResponseBody); Assert.NotNull(ser.Exception); } } }
public void SendCanBeCalledAfterStateChangedEvent(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/multisend"); var results = new List <string>(); connection.Received += data => { results.Add(data); }; connection.StateChanged += stateChange => { if (stateChange.NewState == Client.ConnectionState.Connected) { connection.SendWithTimeout(""); } }; connection.Start(host.Transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); } }
public async Task ConnectionIdsCantBeUsedAsGroups() { using (var host = new MemoryHost()) { IProtectedData protectedData = null; host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR <MyConnection>("/echo", config); protectedData = config.Resolver.Resolve <IProtectedData>(); }); var connection = new Client.Connection("http://memoryhost/echo"); using (connection) { var connectionTcs = new TaskCompletionSource <string>(); var spyTcs = new TaskCompletionSource <string>(); connection.Received += data => { connectionTcs.SetResult(data.Trim()); }; await connection.Start(host).OrTimeout(); EventSourceStreamReader reader = null; await Task.Run(async() => { var url = GetUrl(protectedData, connection); var response = await host.Get(url, r => { }, isLongRunning: true); reader = new EventSourceStreamReader(connection, response.GetStream()); reader.Message = sseEvent => { if (sseEvent.EventType == EventType.Data && sseEvent.Data != "initialized" && sseEvent.Data != "{}") { spyTcs.TrySetResult(sseEvent.Data); } }; reader.Start(); }); await connection.Send("STUFFF").OrTimeout(); Assert.Equal("STUFFF", await connectionTcs.Task.OrTimeout()); } } }
public async Task FarmDisconnectRaisesUncleanDisconnects() { EnableTracing(); // Each node shares the same bus but are indepenent servers var counters = new SignalR.Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); var protectedData = new DefaultProtectedData(); using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) { var nodeCount = 3; var nodes = new List <ServerNode>(); for (int i = 0; i < nodeCount; i++) { nodes.Add(new ServerNode(bus)); } var timeout = TimeSpan.FromSeconds(5); foreach (var node in nodes) { var config = node.Resolver.Resolve <IConfigurationManager>(); config.DisconnectTimeout = TimeSpan.FromSeconds(6); IDependencyResolver resolver = node.Resolver; node.Server.Configure(app => { app.MapSignalR <FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); resolver.Register(typeof(IProtectedData), () => protectedData); }); } var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray()); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodes.Count; i++) { nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(timeout.Ticks *nodes.Count)); Assert.Equal(0, FarmConnection.CleanDisconnectCount); Assert.Equal(3, FarmConnection.UncleanDisconnectCount); } }
public void FarmDisconnectOnlyRaisesEventOnce() { EnableTracing(); // Each node shares the same bus but are indepenent servers var counters = new SignalR.Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) { var nodeCount = 3; var nodes = new List <ServerNode>(); for (int i = 0; i < nodeCount; i++) { nodes.Add(new ServerNode(bus)); } var timeout = TimeSpan.FromSeconds(5); foreach (var node in nodes) { var config = node.Resolver.Resolve <IConfigurationManager>(); config.DisconnectTimeout = TimeSpan.FromSeconds(6); IDependencyResolver resolver = node.Resolver; node.Server.Configure(app => { app.MapConnection <FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); } var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray()); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); connection.Start(transport).Wait(); for (int i = 0; i < nodes.Count; i++) { nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)); Thread.Sleep(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count)); Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount)); } }
public static IDisposable ClientGroupsSyncWithServerGroupsOnReconnectLongPolling() { var host = new MemoryHost(); host.Configuration.KeepAlive = null; host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(5); host.Configuration.HeartbeatInterval = TimeSpan.FromSeconds(2); host.MapConnection <MyRejoinGroupConnection>("/groups"); var connection = new Client.Connection("http://foo/groups"); var inGroupOnReconnect = new List <bool>(); var wh = new ManualResetEventSlim(); connection.Received += message => { Console.WriteLine(message); wh.Set(); }; connection.Reconnected += () => { var inGroup = connection.Groups.Contains(typeof(MyRejoinGroupConnection).FullName + ".test"); if (!inGroup) { Debugger.Break(); } inGroupOnReconnect.Add(inGroup); connection.Send(new { type = 3, group = "test", message = "Reconnected" }).Wait(); }; connection.Start(new Client.Transports.LongPollingTransport(host)).Wait(); // Join the group connection.Send(new { type = 1, group = "test" }).Wait(); Thread.Sleep(TimeSpan.FromSeconds(10)); if (!wh.Wait(TimeSpan.FromSeconds(10))) { Debugger.Break(); } Console.WriteLine(inGroupOnReconnect.Count > 0); Console.WriteLine(String.Join(", ", inGroupOnReconnect.Select(b => b.ToString()))); connection.Stop(); return(host); }
public static IDisposable ClientGroupsSyncWithServerGroupsOnReconnectLongPolling() { var host = new MemoryHost(); host.Configure(app => { var config = new ConnectionConfiguration() { Resolver = new DefaultDependencyResolver() }; app.MapConnection <MyRejoinGroupConnection>("/groups", config); var configuration = config.Resolver.Resolve <IConfigurationManager>(); configuration.KeepAlive = null; configuration.ConnectionTimeout = TimeSpan.FromSeconds(1); }); var connection = new Client.Connection("http://foo/groups"); var inGroupOnReconnect = new List <bool>(); var wh = new ManualResetEventSlim(); connection.Received += message => { Console.WriteLine(message); wh.Set(); }; connection.Reconnected += () => { connection.Send(new { type = 3, group = "test", message = "Reconnected" }).Wait(); }; connection.Start(new Client.Transports.LongPollingTransport(host)).Wait(); // Join the group connection.Send(new { type = 1, group = "test" }).Wait(); Thread.Sleep(TimeSpan.FromSeconds(10)); if (!wh.Wait(TimeSpan.FromSeconds(10))) { Debugger.Break(); } Console.WriteLine(inGroupOnReconnect.Count > 0); Console.WriteLine(String.Join(", ", inGroupOnReconnect.Select(b => b.ToString()))); connection.Stop(); return(host); }
public static IDisposable ClientGroupsSyncWithServerGroupsOnReconnectLongPolling() { var host = new MemoryHost(); host.Configuration.KeepAlive = null; host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(5); host.Configuration.HeartbeatInterval = TimeSpan.FromSeconds(2); host.MapConnection<MyRejoinGroupConnection>("/groups"); var connection = new Client.Connection("http://foo/groups"); var inGroupOnReconnect = new List<bool>(); var wh = new ManualResetEventSlim(); connection.Received += message => { Console.WriteLine(message); wh.Set(); }; connection.Reconnected += () => { var inGroup = connection.Groups.Contains(typeof(MyRejoinGroupConnection).FullName + ".test"); if (!inGroup) { Debugger.Break(); } inGroupOnReconnect.Add(inGroup); connection.Send(new { type = 3, group = "test", message = "Reconnected" }).Wait(); }; connection.Start(new Client.Transports.LongPollingTransport(host)).Wait(); // Join the group connection.Send(new { type = 1, group = "test" }).Wait(); Thread.Sleep(TimeSpan.FromSeconds(10)); if (!wh.Wait(TimeSpan.FromSeconds(10))) { Debugger.Break(); } Console.WriteLine(inGroupOnReconnect.Count > 0); Console.WriteLine(String.Join(", ", inGroupOnReconnect.Select(b => b.ToString()))); connection.Stop(); return host; }
public void FailedNegotiateShouldNotBeActive() { var connection = new Client.Connection("http://test"); var transport = new Mock<IClientTransport>(); transport.Setup(m => m.Negotiate(connection)) .Returns(TaskAsyncHelper.FromError<NegotiationResponse>(new InvalidOperationException("Something failed."))); var aggEx = Assert.Throws<AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(InvalidOperationException), ex); Assert.Equal("Something failed.", ex.Message); Assert.Equal(ConnectionState.Disconnected, connection.State); }
public async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); configurationManager.DisconnectTimeout = TimeSpan.FromSeconds(6); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount)) { var broadcasters = new List <IConnection>(); var disconnectCounter = new DisconnectCounter(); loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); resolver.Register(typeof(IConfigurationManager), () => configurationManager); resolver.Register(typeof(FarmConnection), () => new FarmConnection(disconnectCounter)); var connectionManager = resolver.Resolve <IConnectionManager>(); broadcasters.Add(connectionManager.GetConnectionContext <FarmConnection>().Connection); app.MapSignalR <FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodeCount; i++) { broadcasters[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)).Wait(); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(TimeSpan.FromSeconds(5).Ticks *nodeCount)); Assert.Equal(0, disconnectCounter.CleanDisconnectCount); Assert.Equal(3, disconnectCounter.UncleanDisconnectCount); } }
public async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); configurationManager.DisconnectTimeout = TimeSpan.FromSeconds(6); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount)) { var broadcasters = new List<IConnection>(); var disconnectCounter = new DisconnectCounter(); loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); resolver.Register(typeof(IConfigurationManager), () => configurationManager); resolver.Register(typeof(FarmConnection), () => new FarmConnection(disconnectCounter)); var connectionManager = resolver.Resolve<IConnectionManager>(); broadcasters.Add(connectionManager.GetConnectionContext<FarmConnection>().Connection); app.MapSignalR<FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodeCount; i++) { broadcasters[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)).Wait(); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(TimeSpan.FromSeconds(5).Ticks * nodeCount)); Assert.Equal(0, disconnectCounter.CleanDisconnectCount); Assert.Equal(3, disconnectCounter.UncleanDisconnectCount); } }
public void FailedNegotiateShouldBeDisconnected() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())) .Returns(TaskAsyncHelper.FromError <NegotiationResponse>(new InvalidOperationException("Something failed."))); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(InvalidOperationException), ex); Assert.Equal("Something failed.", ex.Message); Assert.Equal(ConnectionState.Disconnected, connection.State); }
public void SendWithSyncErrorThrows(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/sync-error"); connection.Start(host.Transport).Wait(); Assert.Throws <AggregateException>(() => connection.SendWithTimeout("test")); connection.Stop(); } }
public void EnvironmentIsAvailable(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/items"); var connection2 = new Client.Connection(host.Url + "/items"); var results = new List <RequestItemsResponse>(); connection2.Received += data => { var val = JsonConvert.DeserializeObject <RequestItemsResponse>(data); if (!results.Contains(val)) { results.Add(val); } }; connection.Start(host.Transport).Wait(); connection2.Start(host.Transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(2)); connection.SendWithTimeout(null); Thread.Sleep(TimeSpan.FromSeconds(2)); connection.Stop(); Thread.Sleep(TimeSpan.FromSeconds(2)); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(3, results.Count); Assert.Equal("OnConnectedAsync", results[0].Method); Assert.Equal(1, results[0].Keys.Length); Assert.Equal("owin.environment", results[0].Keys[0]); Assert.Equal("OnReceivedAsync", results[1].Method); Assert.Equal(1, results[1].Keys.Length); Assert.Equal("owin.environment", results[1].Keys[0]); Assert.Equal("OnDisconnectAsync", results[2].Method); Assert.Equal(1, results[2].Keys.Length); Assert.Equal("owin.environment", results[2].Keys[0]); connection2.Stop(); } }
public void NegotiatePassesClientProtocolCorrectly(string clientProtocolParameter, string connectionQueryString) { var connection = new Client.Connection("http://test", connectionQueryString); try { connection.Start(new LongPollingTransport(new UrlInspectingHttpClient((url) => { Assert.True(url.Contains(clientProtocolParameter + connection.Protocol.ToString())); }))).Wait(); } catch { // Swallow exceptions because the custom http client that we pass will throw unimplemented exceptions. } }
public void GroupsAreNotReadOnConnectedAsync() { var host = new MemoryHost(); host.MapConnection<MyConnection>("/echo"); var connection = new Client.Connection("http://foo/echo"); connection.Groups = new List<string> { typeof(MyConnection).FullName + ".test" }; connection.Received += data => { Assert.False(true, "Unexpectedly received data"); }; connection.Start(host).Wait(); Thread.Sleep(TimeSpan.FromSeconds(10)); }
public void FailsIfProtocolVersionIsNull() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())).Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = null })); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(InvalidOperationException), ex); Assert.Equal("You are using a version of the client that isn't compatible with the server. Client version " + connection.Protocol.ToString() + ", server version null.", ex.Message); }
public void StartShouldBeConnected() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection)) .Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = "1.2", ConnectionId = "Something" })); transport.Setup(m => m.Start(connection, null, It.IsAny <CancellationToken>())) .Returns(TaskAsyncHelper.Empty); connection.Start(transport.Object).Wait(); Assert.Equal(ConnectionState.Connected, connection.State); }
public void AsyncStartShouldBeConnected() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())) .Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = connection.Protocol.ToString(), ConnectionId = "Something" })); transport.Setup(m => m.Start(connection, null, It.IsAny <CancellationToken>())) .Returns(TaskAsyncHelper.Delay(TimeSpan.FromMilliseconds(100))); Assert.True(connection.Start(transport.Object).Wait(TimeSpan.FromSeconds(5)), "Start hung."); Assert.Equal(ConnectionState.Connected, connection.State); }
// [InlineData(HostType.IIS, TransportType.LongPolling)] public void ReconnectFiresAfterHostShutDown(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/my-reconnect"); connection.Start(host.Transport).Wait(); host.Shutdown(); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.Equal(Client.ConnectionState.Reconnecting, connection.State); connection.Stop(); } }
private static void Main() { const string url = "http://*****:*****@ {1}", connection.Url, DateTime.Now); connection.Send("Hello Server"); Thread.Sleep(2000); } } catch (Exception exception) { Console.WriteLine(exception); } } }); Console.ReadLine(); }
public void ThrownWebExceptionShouldBeUnwrapped() { var host = new MemoryHost(); host.MapConnection<MyBadConnection>("/ErrorsAreFun"); var connection = new Client.Connection("http://test/ErrorsAreFun"); // Expecting 404 var aggEx = Assert.Throws<AggregateException>(() => connection.Start(host).Wait()); connection.Stop(); using (var ser = aggEx.GetError()) { Assert.Equal(ser.StatusCode, HttpStatusCode.NotFound); Assert.NotNull(ser.ResponseBody); Assert.NotNull(ser.Exception); } }
public void CancelledNegotiateShouldBeDisconnected() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())) .Returns(() => { var tcs = new TaskCompletionSource <NegotiationResponse>(); tcs.SetCanceled(); return(tcs.Task); }); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(TaskCanceledException), ex); Assert.Equal(ConnectionState.Disconnected, connection.State); }
public void FailedStartShouldNotBeActive() { var connection = new Client.Connection("http://test"); var transport = new Mock<IClientTransport>(); transport.Setup(m => m.Negotiate(connection)) .Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = "1.2", ConnectionId = "Something" })); transport.Setup(m => m.Start(connection, null, It.IsAny<CancellationToken>())) .Returns(TaskAsyncHelper.FromError(new InvalidOperationException("Something failed."))); var aggEx = Assert.Throws<AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(InvalidOperationException), ex); Assert.Equal("Something failed.", ex.Message); Assert.Equal(ConnectionState.Disconnected, connection.State); }
public void ReconnectFiresAfterHostShutDown() { using (var host = new MemoryHost()) { var conn = new MyReconnect(); host.DependencyResolver.Register(typeof(MyReconnect), () => conn); host.MapConnection <MyReconnect>("/endpoint"); var connection = new Client.Connection("http://foo/endpoint"); connection.Start(host).Wait(); host.Dispose(); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.Equal(Client.ConnectionState.Reconnecting, connection.State); connection.Stop(); } }
public void GroupsAreNotReadOnConnectedAsync(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/group-echo"); ((Client.IConnection)connection).Groups.Add(typeof(MyGroupEchoConnection).FullName + ".test"); connection.Received += data => { Assert.False(true, "Unexpectedly received data"); }; connection.Start(host.Transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); } }
public void ClientGroupsSyncWithServerGroupsOnReconnect(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(keepAlive: 0, connectionTimeout: 5, hearbeatInterval: 2); var connection = new Client.Connection(host.Url + "/rejoin-groups"); var inGroupOnReconnect = new List<bool>(); var wh = new ManualResetEventSlim(); connection.Received += message => { Assert.Equal("Reconnected", message); wh.Set(); }; connection.Reconnected += () => { inGroupOnReconnect.Add(connection.Groups.Contains(typeof(MyRejoinGroupsConnection).FullName + ".test")); connection.SendWithTimeout(new { type = 3, group = "test", message = "Reconnected" }); }; connection.Start(host.Transport).Wait(); // Join the group connection.SendWithTimeout(new { type = 1, group = "test" }); // Force reconnect Thread.Sleep(TimeSpan.FromSeconds(10)); Assert.True(wh.Wait(TimeSpan.FromSeconds(5)), "Client didn't receive message sent to test group."); Assert.True(inGroupOnReconnect.Count > 0); Assert.True(inGroupOnReconnect.All(b => b)); connection.Stop(); } }
public void DisconnectFiresForPersistentConnectionWhenClientGoesAway() { var host = new MemoryHost(); host.MapConnection<MyConnection>("/echo"); host.Configuration.DisconnectTimeout = TimeSpan.Zero; host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(5); var connectWh = new ManualResetEventSlim(); var disconnectWh = new ManualResetEventSlim(); host.DependencyResolver.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); var connection = new Client.Connection("http://foo/echo"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(host.Configuration.HeartBeatInterval.Ticks * 3); connection.Start(host).Wait(); Assert.True(connectWh.Wait(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(disconnectWh.Wait(disconnectWait), "Disconnect never fired"); }
public void ReconnectFiresAfterTimeOut(TransportType transportType) { using (var host = new MemoryHost()) { var conn = new MyReconnect(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapConnection<MyReconnect>("/endpoint", config); var configuration = config.Resolver.Resolve<IConfigurationManager>(); configuration.KeepAlive = 0; configuration.ConnectionTimeout = TimeSpan.FromSeconds(5); configuration.HeartbeatInterval = TimeSpan.FromSeconds(5); config.Resolver.Register(typeof(MyReconnect), () => conn); }); var connection = new Client.Connection("http://foo/endpoint"); var transport = CreateTransport(transportType, host); connection.Start(transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(15)); connection.Stop(); Assert.InRange(conn.Reconnects, 1, 4); } }
public void EnvironmentIsAvailable(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/items"); var connection2 = new Client.Connection(host.Url + "/items"); var results = new List<RequestItemsResponse>(); connection2.Received += data => { var val = JsonConvert.DeserializeObject<RequestItemsResponse>(data); if (!results.Contains(val)) { results.Add(val); } }; connection.Start(host.Transport).Wait(); connection2.Start(host.Transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(2)); connection.SendWithTimeout(null); Thread.Sleep(TimeSpan.FromSeconds(2)); connection.Stop(); Thread.Sleep(TimeSpan.FromSeconds(2)); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(3, results.Count); Assert.Equal("OnConnectedAsync", results[0].Method); Assert.Equal(1, results[0].Keys.Length); Assert.Equal("owin.environment", results[0].Keys[0]); Assert.Equal("OnReceivedAsync", results[1].Method); Assert.Equal(1, results[1].Keys.Length); Assert.Equal("owin.environment", results[1].Keys[0]); Assert.Equal("OnDisconnectAsync", results[2].Method); Assert.Equal(1, results[2].Keys.Length); Assert.Equal("owin.environment", results[2].Keys[0]); connection2.Stop(); } }
public void SendWithSyncErrorThrows(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/sync-error"); connection.Start(host.Transport).Wait(); Assert.Throws<AggregateException>(() => connection.SendWithTimeout("test")); connection.Stop(); } }
public void ReconnectFiresAfterHostShutDown() { var host = new MemoryHost(); var conn = new MyReconnect(); host.DependencyResolver.Register(typeof(MyReconnect), () => conn); host.MapConnection<MyReconnect>("/endpoint"); var connection = new Client.Connection("http://foo/endpoint"); connection.Start(host).Wait(); host.Dispose(); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.Equal(Client.ConnectionState.Reconnecting, connection.State); connection.Stop(); }
public void SendCanBeCalledAfterStateChangedEvent(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/multisend"); var results = new List<string>(); connection.Received += data => { results.Add(data); }; connection.StateChanged += stateChange => { if (stateChange.NewState == Client.ConnectionState.Connected) { connection.SendWithTimeout(""); } }; connection.Start(host.Transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); } }
public void ReconnectFiresAfterTimeOutSSE() { var host = new MemoryHost(); var conn = new MyReconnect(); host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(5); host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(1); host.DependencyResolver.Register(typeof(MyReconnect), () => conn); host.MapConnection<MyReconnect>("/endpoint"); var connection = new Client.Connection("http://foo/endpoint"); connection.Start(host).Wait(); Thread.Sleep(TimeSpan.FromSeconds(15)); Assert.Equal(2, conn.Reconnects); }
public void FarmDisconnectOnlyRaisesEventOnce() { // Each node shares the same bus but are indepenent servers var bus = new InProcessMessageBus(new TraceManager(), garbageCollectMessages: false); var nodeCount = 3; var nodes = new List<ServerNode>(); for (int i = 0; i < nodeCount; i++) { nodes.Add(new ServerNode(bus)); } var timeout = TimeSpan.FromSeconds(5); foreach (var node in nodes) { node.Server.Configuration.HeartBeatInterval = timeout; node.Server.Configuration.DisconnectTimeout = TimeSpan.Zero; node.Server.MapConnection<FarmConnection>("/echo"); } var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray()); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); connection.Start(transport).Wait(); for (int i = 0; i < nodes.Count; i++) { nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)); Thread.Sleep(TimeSpan.FromSeconds(1)); } Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count)); Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount)); }
public void GroupsReceiveMessages() { var host = new MemoryHost(); host.MapConnection<MyGroupConnection>("/groups"); var connection = new Client.Connection("http://foo/groups"); var list = new List<string>(); connection.Received += data => { list.Add(data); }; connection.Start(host).Wait(); // Join the group connection.Send(new { type = 1, group = "test" }).Wait(); // Sent a message connection.Send(new { type = 3, group = "test", message = "hello to group test" }).Wait(); // Leave the group connection.Send(new { type = 2, group = "test" }).Wait(); // Send a message connection.Send(new { type = 3, group = "test", message = "goodbye to group test" }).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(1, list.Count); Assert.Equal("hello to group test", list[0]); }
public void GroupsRejoinedWhenOnRejoiningGroupsOverridden() { var host = new MemoryHost(); host.Configuration.KeepAlive = null; host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(2); host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(2); host.MapConnection<MyRejoinGroupConnection>("/groups"); var connection = new Client.Connection("http://foo/groups"); var list = new List<string>(); connection.Received += data => { list.Add(data); }; connection.Start(host).Wait(); // Join the group connection.Send(new { type = 1, group = "test" }).Wait(); // Sent a message connection.Send(new { type = 3, group = "test", message = "hello to group test" }).Wait(); // Force Reconnect Thread.Sleep(TimeSpan.FromSeconds(5)); // Send a message connection.Send(new { type = 3, group = "test", message = "goodbye to group test" }).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(2, list.Count); Assert.Equal("hello to group test", list[0]); Assert.Equal("goodbye to group test", list[1]); }
public void ReconnectFiresAfterHostShutDown(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/my-reconnect"); connection.Start(host.Transport).Wait(); host.Shutdown(); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.Equal(Client.ConnectionState.Reconnecting, connection.State); connection.Stop(); } }
public void ReconnectDoesntFireAfterTimeOut(TransportType transportType, MessageBusType messageBusType) { using (var host = new MemoryHost()) { var conn = new MyReconnect(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; UseMessageBus(messageBusType, config.Resolver); app.MapSignalR<MyReconnect>("/endpoint", config); var configuration = config.Resolver.Resolve<IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.ConnectionTimeout = TimeSpan.FromSeconds(2); configuration.KeepAlive = null; config.Resolver.Register(typeof(MyReconnect), () => conn); }); var connection = new Client.Connection("http://foo/endpoint"); var transport = CreateTransport(transportType, host); connection.Start(transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Assert.Equal(0, conn.Reconnects); } }
public void SendRaisesOnReceivedFromAllEvents(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { host.Initialize(); var connection = new Client.Connection(host.Url + "/multisend"); var results = new List<string>(); connection.Received += data => { results.Add(data); }; connection.Start(host.Transport).Wait(); connection.SendWithTimeout(""); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); Assert.Equal("OnConnectedAsync1", results[0]); Assert.Equal("OnConnectedAsync2", results[1]); Assert.Equal("OnReceivedAsync1", results[2]); Assert.Equal("OnReceivedAsync2", results[3]); } }
public void SendToClientFromOutsideOfConnection() { 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 ManualResetEventSlim(initialState: false); connection1.Start(host).Wait(); connection1.Received += data => { Assert.Equal("yay", data); wh1.Set(); }; connectionContext.Connection.Send(connection1.ConnectionId, "yay"); Assert.True(wh1.Wait(TimeSpan.FromSeconds(10))); } } }
public void SendToAllButCaller() { var host = new MemoryHost(); host.MapConnection<FilteredConnection>("/filter"); var connection1 = new Client.Connection("http://foo/filter"); var connection2 = new Client.Connection("http://foo/filter"); var wh1 = new ManualResetEventSlim(initialState: false); var wh2 = new ManualResetEventSlim(initialState: false); connection1.Received += data => wh1.Set(); connection2.Received += data => wh2.Set(); connection1.Start(host).Wait(); connection2.Start(host).Wait(); connection1.Send("test").Wait(); Assert.False(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); connection1.Stop(); connection2.Stop(); }
public void SendRaisesOnReceivedFromAllEvents() { var host = new MemoryHost(); host.MapConnection<MySendingConnection>("/multisend"); var connection = new Client.Connection("http://foo/multisend"); var results = new List<string>(); connection.Received += data => { results.Add(data); }; connection.Start(host).Wait(); connection.Send("").Wait(); Thread.Sleep(TimeSpan.FromSeconds(10)); Debug.WriteLine(String.Join(", ", results)); Assert.Equal(4, results.Count); Assert.Equal("OnConnectedAsync1", results[0]); Assert.Equal("OnConnectedAsync2", results[1]); Assert.Equal("OnReceivedAsync1", results[2]); Assert.Equal("OnReceivedAsync2", results[3]); }
public void ReconnectFiresAfterTimeOutSSE() { var host = new MemoryHost(); var conn = new MyReconnect(); host.Configuration.KeepAlive = null; host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(5); host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(5); host.DependencyResolver.Register(typeof(MyReconnect), () => conn); host.MapConnection<MyReconnect>("/endpoint"); var connection = new Client.Connection("http://foo/endpoint"); connection.Start(new Client.Transports.ServerSentEventsTransport(host)).Wait(); Thread.Sleep(TimeSpan.FromSeconds(15)); connection.Stop(); Assert.InRange(conn.Reconnects, 1, 4); }