public void ConnectionsWithTheSameConnectionIdLongPollingCloseGracefully() { var host = new MemoryHost(); host.MapConnection <MyConnection>("/echo"); var tasks = new List <Task>(); for (int i = 0; i < 1000; i++) { tasks.Add(ProcessRequest(host, "longPolling", "1")); } ProcessRequest(host, "longPolling", "1"); Task.WaitAll(tasks.ToArray()); Assert.True(tasks.All(t => !t.IsFaulted)); }
public static void SendLoop() { var host = new MemoryHost(); host.Configure(app => { var config = new HubConfiguration() { Resolver = new DefaultDependencyResolver() }; config.Resolver.Resolve <IConfigurationManager>().ConnectionTimeout = TimeSpan.FromDays(1); app.MapSignalR(config); }); var connection = new HubConnection("http://foo"); var proxy = connection.CreateHubProxy("SimpleEchoHub"); var wh = new ManualResetEventSlim(false); proxy.On("echo", _ => wh.Set()); try { connection.Start(new Client.Transports.LongPollingTransport(host)).Wait(); while (true) { proxy.Invoke("Echo", "foo").Wait(); if (!wh.Wait(TimeSpan.FromSeconds(10))) { Debugger.Break(); } wh.Reset(); } } catch { connection.Stop(); } }
public void ReadingState() { var host = new MemoryHost(); host.MapHubs(); var connection = new Client.Hubs.HubConnection("http://foo/"); var hub = connection.CreateProxy("demo"); hub["name"] = "test"; connection.Start(host).Wait(); var result = hub.Invoke <string>("ReadStateValue").Result; Assert.Equal("test", result); connection.Stop(); }
public async Task SendToAllFromOutsideOfHub() { 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/"); var connection2 = new HubConnection("http://foo/"); using (connection1) using (connection2) { var wh1 = new TaskCompletionSource <object>(); var wh2 = new TaskCompletionSource <object>(); var hub1 = connection1.CreateHubProxy("SendToSome"); var hub2 = connection2.CreateHubProxy("SendToSome"); await connection1.Start(host); await connection2.Start(host); hub1.On("send", () => wh1.TrySetResult(null)); hub2.On("send", () => wh2.TrySetResult(null)); hubContext.Clients.All.send(); await wh1.Task.OrTimeout(TimeSpan.FromSeconds(10)); await wh2.Task.OrTimeout(TimeSpan.FromSeconds(10)); } } }
public void InitMessageSentToFallbackTransports() { using (var host = new MemoryHost()) { host.Configure(app => { Func <AppFunc, AppFunc> middleware = (next) => { return(env => { var request = new OwinRequest(env); var response = new OwinResponse(env); if (!request.Path.Value.Contains("negotiate") && !request.QueryString.Value.Contains("longPolling")) { response.Body = new MemoryStream(); } return next(env); }); }; app.Use(middleware); var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR <MyConnection>("/echo", config); }); var connection = new Connection("http://foo/echo"); using (connection) { connection.Start(host).Wait(); Assert.Equal(connection.State, ConnectionState.Connected); Assert.Equal(connection.Transport.Name, "longPolling"); } } }
public async Task SendToUser() { using (var host = new MemoryHost()) { host.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IUserIdProvider), () => new UserIdProvider()); var config = new HubConfiguration { Resolver = resolver }; app.MapSignalR(config); }); var connection1 = CreateHubConnection("user1"); var connection2 = CreateHubConnection("user2"); var wh1 = new TaskCompletionSource <object>(); var wh2 = new TaskCompletionSource <object>(); var hub1 = connection1.CreateHubProxy("EchoHub"); var hub2 = connection2.CreateHubProxy("EchoHub"); hub1.On("echo", () => wh1.TrySetResult(null)); hub2.On("echo", () => wh2.TrySetResult(null)); using (connection1) { using (connection2) { await connection1.Start(host); await connection2.Start(host); await hub2.Invoke("SendToUser", "user1", "message"); await wh1.Task.OrTimeout(); Assert.False(wh2.Task.IsCompleted); } } } }
public async Task SendToAllFromOutsideOfHub() { 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/"); var connection2 = new HubConnection("http://foo/"); using (connection1) using (connection2) { var wh1 = new AsyncManualResetEvent(initialState: false); var wh2 = new AsyncManualResetEvent(initialState: false); var hub1 = connection1.CreateHubProxy("SendToSome"); var hub2 = connection2.CreateHubProxy("SendToSome"); await connection1.Start(host); await connection2.Start(host); hub1.On("send", wh1.Set); hub2.On("send", wh2.Set); hubContext.Clients.All.send(); Assert.True(await wh1.WaitAsync(TimeSpan.FromSeconds(10))); Assert.True(await wh2.WaitAsync(TimeSpan.FromSeconds(10))); } } }
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 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 ConnectionsWithTheSameConnectionIdSSECloseGracefully() { using (var host = new MemoryHost()) { host.MapConnection <MyGroupEchoConnection>("/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 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 CustomQueryString() { var host = new MemoryHost(); host.MapHubs(); var qs = new Dictionary <string, string>(); qs["a"] = "b"; var connection = new Client.Hubs.HubConnection("http://foo/", qs); var hub = connection.CreateProxy("CustomQueryHub"); connection.Start(host).Wait(); var result = hub.Invoke <string>("GetQueryString", "a").Result; Assert.Equal("b", result); connection.Stop(); }
public void ConnectionCanStartWithAuthenicatedUserAndQueryString() { using (var host = new MemoryHost()) { host.Configure(app => { Func <AppFunc, AppFunc> middleware = (next) => { return(env => { if (((string)env["owin.RequestQueryString"]).IndexOf("access_token") == -1) { return next(env); } var user = new CustomPrincipal { Name = "Bob", IsAuthenticated = true, Roles = new[] { "User" } }; env["server.User"] = user; return next(env); }); }; app.Use(middleware); app.MapConnection <MyAuthenticatedConnection>("/authenticatedConnection", new ConnectionConfiguration()); }); var connection = new Connection("http://foo/authenticatedConnection", "access_token=1234"); connection.Start(host).Wait(); Assert.Equal(connection.State, ConnectionState.Connected); connection.Stop(); } }
public void DynamicInvokeTest() { var host = new MemoryHost(); host.MapHubs(); var connection = new Client.Hubs.HubConnection("http://site/"); string callback = "!!!CallMeBack!!!"; var hub = connection.CreateProxy("demo"); var wh = new ManualResetEvent(false); hub.On(callback, () => wh.Set()); connection.Start(host).Wait(); hub.Invoke("DynamicInvoke", callback).Wait(); Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5))); connection.Stop(); }
public void ReconnectFiresAfterTimeOutLongPolling() { 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.LongPollingTransport(host)).Wait(); Thread.Sleep(TimeSpan.FromSeconds(15)); connection.Stop(); Assert.InRange(conn.Reconnects, 1, 4); } }
public static IDisposable RunConnectDisconnect(int connections) { var host = new MemoryHost(); host.Configure(app => { var config = new HubConfiguration() { Resolver = new DefaultDependencyResolver() }; app.MapHubs(config); }); for (int i = 0; i < connections; i++) { var connection = new Client.Hubs.HubConnection("http://foo"); var proxy = connection.CreateHubProxy("EchoHub"); var wh = new ManualResetEventSlim(false); proxy.On("echo", _ => wh.Set()); try { connection.Start(host).Wait(); proxy.Invoke("Echo", "foo").Wait(); if (!wh.Wait(TimeSpan.FromSeconds(10))) { Debugger.Break(); } } finally { connection.Stop(); } } return(host); }
public static void Scaleout(int nodes, int clients) { var hosts = new MemoryHost[nodes]; var random = new Random(); var eventBus = new EventBus(); var protectedData = new DefaultProtectedData(); for (var i = 0; i < nodes; ++i) { var host = new MemoryHost(); host.Configure(app => { var config = new HubConfiguration() { Resolver = new DefaultDependencyResolver() }; var delay = i % 2 == 0 ? TimeSpan.Zero : TimeSpan.FromSeconds(1); var bus = new DelayedMessageBus(host.InstanceName, eventBus, config.Resolver, delay); config.Resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(config); config.Resolver.Register(typeof(IProtectedData), () => protectedData); }); hosts[i] = host; } var client = new LoadBalancer(hosts); var wh = new ManualResetEventSlim(); for (int i = 0; i < clients; i++) { Task.Run(() => RunLoop(client, wh)); } wh.Wait(); }
public void GroupsAreNotReadOnConnectedAsync() { 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"); }; connection.Start(host).Wait(); Thread.Sleep(TimeSpan.FromSeconds(5)); connection.Stop(); } }
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 async Task SendToUserFromOutsideOfHub() { using (var host = new MemoryHost()) { IHubContext <IBasicClient> hubContext = HubFacts.InitializeUserByQuerystring(host); var wh = new TaskCompletionSource <object>(); using (var connection = HubFacts.GetUserConnection("myuser")) { var hub = connection.CreateHubProxy("SendToSome"); await connection.Start(host); hub.On("send", () => wh.TrySetResult(null)); hubContext.Clients.User("myuser").send(); await wh.Task.OrTimeout(TimeSpan.FromSeconds(10)); } } }
private static void RunOne(MemoryHost host) { var connection = new Client.Hubs.HubConnection("http://foo"); var proxy = connection.CreateHubProxy("OnConnectedOnDisconnectedHub"); try { connection.Start(host).Wait(); string guid = Guid.NewGuid().ToString(); string otherGuid = proxy.Invoke <string>("Echo", guid).Result; if (!guid.Equals(otherGuid)) { throw new InvalidOperationException("Fail!"); } } finally { connection.Stop(); } }
public void HubNamesAreNotCaseSensitive() { var host = new MemoryHost(); host.MapHubs(); var hubConnection = new HubConnection("http://fake"); IHubProxy proxy = hubConnection.CreateProxy("chatHub"); var wh = new ManualResetEvent(false); proxy.On("addMessage", data => { Assert.Equal("hello", data); wh.Set(); }); hubConnection.Start(host).Wait(); proxy.Invoke("Send", "hello").Wait(); Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5))); }
public async Task SendToUserFromOutsideOfHub() { using (var host = new MemoryHost()) { IHubContext <IBasicClient> hubContext = HubFacts.InitializeUserByQuerystring(host); var wh = new AsyncManualResetEvent(); using (var connection = HubFacts.GetUserConnection("myuser")) { var hub = connection.CreateHubProxy("SendToSome"); await connection.Start(host); hub.On("send", wh.Set); hubContext.Clients.User("myuser").send(); Assert.True(await wh.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public void SendToSpecificClientFromOutsideOfHub() { var host = new MemoryHost(); host.MapHubs(); var connection1 = new Client.Hubs.HubConnection("http://foo/"); var hubContext = host.ConnectionManager.GetHubContext("SendToSome"); var wh1 = new ManualResetEventSlim(initialState: false); var hub1 = connection1.CreateHubProxy("SendToSome"); connection1.Start(host).Wait(); hub1.On("send", wh1.Set); hubContext.Clients.Client(connection1.ConnectionId).send(); Assert.True(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5))); connection1.Stop(); }
public static IDisposable Connect_Broadcast5msg_AndDisconnect(int concurrency) { var host = new MemoryHost(); var threads = new List <Thread>(); var cancellationTokenSource = new CancellationTokenSource(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = new DefaultDependencyResolver() }; app.MapSignalR <RawConnection>("/Raw-connection", config); }); 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(); })); }
public void DisconnectFiresForHubsWhenConnectionGoesAway() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); var connectWh = new ManualResetEventSlim(); var disconnectWh = new ManualResetEventSlim(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(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 async Task SendToGroupFromOutsideOfConnection() { 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(); }; await connectionContext.Groups.Add(connection1.ConnectionId, "Foo"); await connectionContext.Groups.Send("Foo", "yay"); Assert.True(await wh1.WaitAsync(TimeSpan.FromSeconds(10))); } } }
public static IDisposable ManyUniqueGroups(int concurrency) { var host = new MemoryHost(); var threads = new List <Thread>(); var cancellationTokenSource = new CancellationTokenSource(); host.Configure(app => { var config = new HubConfiguration() { Resolver = new DefaultDependencyResolver() }; app.MapHubs(config); }); for (int i = 0; i < concurrency; i++) { var thread = new Thread(_ => { while (!cancellationTokenSource.IsCancellationRequested) { RunOne(host); } }); threads.Add(thread); thread.Start(); } return(new DisposableAction(() => { cancellationTokenSource.Cancel(); threads.ForEach(t => t.Join()); host.Dispose(); })); }
public async Task DisconnectFiresForHubsWhenClientCallsStop() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); var connectWh = new TaskCompletionSource <object>(); var disconnectWh = new TaskCompletionSource <object>(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3); await connection.Start(host); await connectWh.Task.OrTimeout(TimeSpan.FromSeconds(10)); connection.Stop(); await disconnectWh.Task.OrTimeout(disconnectWait); } }
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 TaskCompletionSource <object>(); await connection1.Start(host); connection1.Received += data => { Assert.Equal("yay", data); wh1.TrySetResult(null); }; await connectionContext.Groups.Add(connection1.ConnectionId, "Foo"); var ignore = connectionContext.Groups.Send(new[] { "Foo", "Bar" }, "yay"); await wh1.Task.OrTimeout(TimeSpan.FromSeconds(10)); } } }