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 Run(int connections, int senders, string payload, string transport) { var host = new MemoryHost(); // Let's not run out of memory everytime host.MapConnection<StressConnection>("/echo"); var countDown = new CountdownEvent(senders); var cancellationTokenSource = new CancellationTokenSource(); for (int i = 0; i < connections; i++) { if (transport.Equals("longPolling", StringComparison.OrdinalIgnoreCase)) { ThreadPool.QueueUserWorkItem(state => { string connectionId = state.ToString(); LongPollingLoop(host, connectionId); }, i); } else { string connectionId = i.ToString(); ProcessRequest(host, transport, connectionId); } } for (var i = 0; i < senders; i++) { ThreadPool.QueueUserWorkItem(_ => { while (!cancellationTokenSource.IsCancellationRequested) { string connectionId = i.ToString(); ProcessSendRequest(host, transport, connectionId, payload); } countDown.Signal(); }); } return new DisposableAction(() => { cancellationTokenSource.Cancel(); // Wait for all senders to stop countDown.Wait(TimeSpan.FromMilliseconds(1000 * senders)); host.Dispose(); }); }
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 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"); }
private static MemoryHost RunMemoryHost() { var host = new MemoryHost(); host.MapConnection<StressConnection>("/echo"); string payload = GetPayload(); MeasureStats((MessageBus)host.DependencyResolver.Resolve<IMessageBus>()); Action<PersistentResponse> handler = (r) => { Interlocked.Add(ref _received, r.TotalCount); Interlocked.Add(ref _avgLastReceivedCount, r.TotalCount); }; LongPollingTransport.SendingResponse += handler; ForeverFrameTransport.SendingResponse += handler; for (int i = 0; i < _clients; i++) { ThreadPool.QueueUserWorkItem(state => { Interlocked.Increment(ref _clientsRunning); string connectionId = state.ToString(); //LongPollingLoop(host, connectionId); ProcessRequest(host, "serverSentEvents", connectionId); }, i); } for (var i = 1; i <= _senders; i++) { ThreadPool.QueueUserWorkItem(_ => { var context = host.ConnectionManager.GetConnectionContext<StressConnection>(); StartSendLoop(i.ToString(), (source, key, value) => context.Connection.Broadcast(value), payload); }); } return host; }
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 ReconnectFiresAfterTimeOutSSE() { using (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); } }
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 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 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); } }
public void GroupsAreNotReadOnConnectedAsyncLongPolling() { using (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"); }; var transport = new Client.Transports.LongPollingTransport(host); connection.Start(transport).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); } }
public void ConnectionsWithTheSameConnectionIdSSECloseGracefully() { using (var host = new MemoryHost()) { host.MapConnection<MyConnection>("/echo"); var tasks = new List<Task>(); for (int i = 0; i < 1000; i++) { tasks.Add(ProcessRequest(host, "serverSentEvents", "1")); } ProcessRequest(host, "serverSentEvents", "1"); Task.WaitAll(tasks.ToArray()); Assert.True(tasks.All(t => !t.IsFaulted)); } }
public void GroupsRejoinedWhenOnRejoiningGroupsOverridden() { using (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 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]); } }
private static void RunInMemoryHost() { var host = new MemoryHost(); host.MapConnection<MyConnection>("/echo"); var connection = new Connection("http://foo/echo"); connection.Received += data => { Console.WriteLine(data); }; connection.StateChanged += change => { Console.WriteLine(change.OldState + " => " + change.NewState); }; connection.Start(host).Wait(); ThreadPool.QueueUserWorkItem(_ => { try { while (true) { connection.Send(DateTime.Now.ToString()); Thread.Sleep(2000); } } catch { } }); }
public static IDisposable Connect_Broadcast5msg_AndDisconnect(int concurrency) { var host = new MemoryHost(); var threads = new List<Thread>(); var cancellationTokenSource = new CancellationTokenSource(); host.MapConnection<RawConnection>("/Raw-connection"); for (int i = 0; i < concurrency; i++) { var thread = new Thread(_ => { while (!cancellationTokenSource.IsCancellationRequested) { BroadcastFive(host); } }); threads.Add(thread); thread.Start(); } return new DisposableAction(() => { cancellationTokenSource.Cancel(); threads.ForEach(t => t.Join()); host.Dispose(); }); }