Skip to content

Commit bdf1603

Browse files
committed
Test same server reroute
1 parent a789992 commit bdf1603

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

test/Microsoft.Azure.SignalR.Tests/Microsoft.Azure.SignalR.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
<ItemGroup>
2020
<FrameworkReference Include="Microsoft.AspNetCore.App" />
21+
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Client" Version="8.0.8" />
22+
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client.Core" Version="8.0.8" />
2123
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
2224
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostPackageVersion)" />
2325
<PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Security.Claims;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.AspNetCore.Connections;
9+
using Microsoft.AspNetCore.Http.Connections.Client;
10+
using Microsoft.AspNetCore.SignalR;
11+
using Microsoft.AspNetCore.SignalR.Client;
12+
using Microsoft.AspNetCore.SignalR.Internal;
13+
using Microsoft.AspNetCore.SignalR.Protocol;
14+
using Microsoft.Azure.SignalR.Protocol;
15+
using Microsoft.Azure.SignalR.Tests.Common;
16+
using Microsoft.Extensions.DependencyInjection;
17+
using Microsoft.Extensions.Logging;
18+
using Microsoft.Extensions.Options;
19+
using Xunit;
20+
using Xunit.Abstractions;
21+
22+
namespace Microsoft.Azure.SignalR.Tests;
23+
24+
#nullable enable
25+
26+
public class SameServerRerouteTests : VerifiableLoggedTest
27+
{
28+
private static int ServerCount = 0;
29+
30+
private static int ClientCount = 0;
31+
32+
public SameServerRerouteTests(ITestOutputHelper output) : base(output)
33+
{
34+
}
35+
36+
[Fact]
37+
public async Task Test()
38+
{
39+
var hub = "foo";
40+
var connectionString = "Endpoint=http://localhost:8080;AccessKey=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGH;Version=1.0;";
41+
42+
using var provider = StartVerifiableLog(out var loggerFactory);
43+
44+
var nameProvider = new DefaultServerNameProvider();
45+
var logger = loggerFactory.CreateLogger<DefaultHubProtocolResolver>();
46+
var hubProtocolResolver = new DefaultHubProtocolResolver(new IHubProtocol[] { new JsonHubProtocol(), new MessagePackHubProtocol() }, logger);
47+
48+
var handler = new EndlessConnectionHandler<TestHub>(loggerFactory);
49+
ConnectionDelegate connectionDelegate = handler.OnConnectedAsync;
50+
51+
var factory = new ServiceConnectionFactory(new ServiceProtocol(),
52+
new ClientConnectionManager(),
53+
new ConnectionFactory(nameProvider, loggerFactory),
54+
loggerFactory,
55+
connectionDelegate,
56+
new ClientConnectionFactory(loggerFactory),
57+
nameProvider,
58+
new DefaultServiceEventHandler(loggerFactory),
59+
new DummyClientInvocationManager(),
60+
hubProtocolResolver);
61+
62+
var serviceEndpoint = new ServiceEndpoint(connectionString);
63+
var serviceEndpointProvider = new ServiceEndpointProvider(serviceEndpoint, new ServiceOptions());
64+
var hubServiceEndpoint = new HubServiceEndpoint(hub, serviceEndpointProvider, serviceEndpoint);
65+
66+
var messageHandler = new StrongServiceConnectionContainer(factory, 1, 1, hubServiceEndpoint, logger);
67+
var ackHandler = new AckHandler();
68+
69+
var connection1 = factory.Create(hubServiceEndpoint, messageHandler, ackHandler, ServiceConnectionType.Default);
70+
var connection2 = factory.Create(hubServiceEndpoint, messageHandler, ackHandler, ServiceConnectionType.Default);
71+
72+
_ = connection1.StartAsync();
73+
_ = connection2.StartAsync();
74+
75+
await Task.Delay(1000);
76+
77+
var audience = $"http://localhost/client/?hub={hub}";
78+
var clientPath = $"http://localhost:8080/client/?hub={hub}";
79+
var accessKey = ConnectionStringParser.Parse(connectionString).AccessKey;
80+
var accessToken = await accessKey.GenerateAccessTokenAsync(audience, Array.Empty<Claim>(), TimeSpan.FromMinutes(1), AccessTokenAlgorithm.HS256);
81+
82+
var connectionOptions = new HttpConnectionOptions();
83+
connectionOptions.Headers.Add("Authorization", $"Bearer {accessToken}");
84+
var connectionFactory = new HttpConnectionFactory(Options.Create(connectionOptions), loggerFactory);
85+
var endpoint = new UriEndPoint(new Uri(clientPath));
86+
87+
var hubConnection = new HubConnection(connectionFactory, new JsonHubProtocol(), endpoint, handler.ServiceProvider, loggerFactory);
88+
89+
hubConnection.On("bar", (int x) => Assert.Equal(Interlocked.Increment(ref ClientCount), x));
90+
91+
_ = hubConnection.StartAsync();
92+
93+
while (true)
94+
{
95+
try
96+
{
97+
await hubConnection.SendAsync(nameof(TestHub.Foo));
98+
}
99+
catch (Exception e)
100+
{
101+
Console.WriteLine(e);
102+
}
103+
await Task.Delay(1000);
104+
}
105+
}
106+
107+
private class TestHub : Hub
108+
{
109+
public Task Foo()
110+
{
111+
var index = Interlocked.Increment(ref ServerCount);
112+
return Clients.Caller.SendAsync("bar", index);
113+
}
114+
115+
public override Task OnConnectedAsync()
116+
{
117+
return Task.CompletedTask;
118+
}
119+
}
120+
121+
private sealed class EndlessConnectionHandler<THub> : ConnectionHandler where THub : Hub
122+
{
123+
public ServiceProvider ServiceProvider { get; }
124+
125+
public EndlessConnectionHandler(ILoggerFactory loggerFactory)
126+
{
127+
var collection = new ServiceCollection();
128+
collection.AddLogging();
129+
collection.AddSingleton(loggerFactory);
130+
collection.AddSingleton<IUserIdProvider, DefaultUserIdProvider>();
131+
collection.AddSingleton<HubConnectionHandler<THub>>();
132+
collection.AddSignalR().AddJsonProtocol();
133+
134+
ServiceProvider = collection.BuildServiceProvider();
135+
}
136+
137+
public override async Task OnConnectedAsync(ConnectionContext connection)
138+
{
139+
var handler = ServiceProvider.GetRequiredService<HubConnectionHandler<TestHub>>();
140+
await handler.OnConnectedAsync(connection);
141+
}
142+
}
143+
144+
private sealed class EndlessHubConnectionContext : HubConnectionContext
145+
{
146+
public EndlessHubConnectionContext(ConnectionContext connectionContext,
147+
HubConnectionContextOptions contextOptions,
148+
ILoggerFactory loggerFactory) : base(connectionContext, contextOptions, loggerFactory)
149+
{
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)