Skip to content

Commit 556fcf3

Browse files
authored
refactor(ITcpSocketFactory): add GetOrCreate extension method (#6277)
* refactor: 更新 ITcpSocketFactory 接口定义 * feat: 增加 GetOrCreate 扩展方法 * test: 更新单元测试 # Conflicts: # test/UnitTest/Services/TcpSocketFactoryTest.cs * test: 增加单元测试
1 parent 0caed5a commit 556fcf3

File tree

5 files changed

+59
-25
lines changed

5 files changed

+59
-25
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
5+
6+
using System.Runtime.Versioning;
7+
8+
namespace BootstrapBlazor.Components;
9+
10+
/// <summary>
11+
/// <see cref="ITcpSocketFactory"/> 扩展方法类
12+
/// </summary>
13+
[UnsupportedOSPlatform("browser")]
14+
public static class ITcpSocketFactoryExtensions
15+
{
16+
/// <summary>
17+
/// Retrieves an existing TCP socket client by name or creates a new one using the specified IP address and port.
18+
/// </summary>
19+
/// <param name="factory">The <see cref="ITcpSocketFactory"/> instance used to manage TCP socket clients.</param>
20+
/// <param name="name">The unique name identifying the TCP socket client. Cannot be null or empty.</param>
21+
/// <param name="ipAddress">The IP address of the endpoint to connect to. Must be a valid IPv4 or IPv6 address.</param>
22+
/// <param name="port">The port number of the endpoint to connect to. Must be within the range 0 to 65535.</param>
23+
/// <returns>An <see cref="ITcpSocketClient"/> instance representing the TCP socket client associated with the specified
24+
/// name. If no client exists with the given name, a new client is created and returned.</returns>
25+
public static ITcpSocketClient GetOrCreate(this ITcpSocketFactory factory, string name, string ipAddress, int port)
26+
{
27+
var endPoint = Utility.ConvertToIpEndPoint(ipAddress, port);
28+
return factory.GetOrCreate(name, endPoint);
29+
}
30+
}

src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketFactory.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ class DefaultTcpSocketFactory(IServiceProvider provider) : ITcpSocketFactory
1616
{
1717
private readonly ConcurrentDictionary<string, ITcpSocketClient> _pool = new();
1818

19-
public ITcpSocketClient GetOrCreate(string host, int port = 0)
19+
public ITcpSocketClient GetOrCreate(string name, IPEndPoint endPoint)
2020
{
21-
return _pool.GetOrAdd($"{host}:{port}", key =>
21+
return _pool.GetOrAdd(name, key =>
2222
{
23-
var endPoint = Utility.ConvertToIpEndPoint(host, port);
2423
var client = new DefaultTcpSocketClient(endPoint)
2524
{
2625
Logger = provider.GetService<ILogger<DefaultTcpSocketClient>>()
@@ -29,10 +28,10 @@ public ITcpSocketClient GetOrCreate(string host, int port = 0)
2928
});
3029
}
3130

32-
public ITcpSocketClient? Remove(string host, int port)
31+
public ITcpSocketClient? Remove(string name)
3332
{
3433
ITcpSocketClient? client = null;
35-
if (_pool.TryRemove($"{host}:{port}", out var c))
34+
if (_pool.TryRemove(name, out var c))
3635
{
3736
client = c;
3837
}

src/BootstrapBlazor/Services/TcpSocket/ITcpSocketFactory.cs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

6+
using System.Net;
7+
68
namespace BootstrapBlazor.Components;
79

810
/// <summary>
@@ -11,21 +13,21 @@ namespace BootstrapBlazor.Components;
1113
public interface ITcpSocketFactory : IDisposable
1214
{
1315
/// <summary>
14-
/// Retrieves an existing TCP socket associated with the specified host and port, or creates a new one if none
15-
/// exists.
16+
/// Retrieves an existing TCP socket client by name or creates a new one if it does not exist.
1617
/// </summary>
17-
/// <param name="host">The hostname or IP address of the remote endpoint. Cannot be null or empty.</param>
18-
/// <param name="port">The port number of the remote endpoint. Must be a valid port number between 0 and 65535.</param>
19-
/// <returns>An <see cref="ITcpSocketClient"/> instance representing the TCP socket for the specified host and port.</returns>
20-
ITcpSocketClient GetOrCreate(string host, int port);
18+
/// <param name="name">The unique name used to identify the TCP socket client. Cannot be null or empty.</param>
19+
/// <param name="endPoint">The network endpoint to associate with the TCP socket client. Must be a valid <see
20+
/// cref="System.Net.IPEndPoint"/> instance.</param>
21+
/// <returns>An instance of <see cref="ITcpSocketClient"/> representing the TCP socket client associated with the specified
22+
/// name and endpoint. If a client with the given name already exists, the existing instance is returned; otherwise,
23+
/// a new client is created.</returns>
24+
ITcpSocketClient GetOrCreate(string name, IPEndPoint endPoint);
2125

2226
/// <summary>
23-
/// Removes the specified host and port combination from the collection.
27+
/// Removes the TCP socket client associated with the specified name.
2428
/// </summary>
25-
/// <remarks>If the specified host and port combination does not exist in the collection, the method has
26-
/// no effect.</remarks>
27-
/// <param name="host">The hostname to remove. Cannot be null or empty.</param>
28-
/// <param name="port">The port number associated with the host to remove. Must be a valid port number (0-65535).</param>
29-
/// <returns>An <see cref="ITcpSocketClient"/> instance representing the TCP socket for the specified host and port.</returns>
30-
ITcpSocketClient? Remove(string host, int port);
29+
/// <param name="name">The name of the TCP socket client to remove. Cannot be <see langword="null"/> or empty.</param>
30+
/// <returns>The removed <see cref="ITcpSocketClient"/> instance if a client with the specified name exists; otherwise, <see
31+
/// langword="null"/>.</returns>
32+
ITcpSocketClient? Remove(string name);
3133
}

test/UnitTest/Services/TcpSocketFactoryTest.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,21 @@ public void GetOrCreate_Ok()
2222
builder.AddProvider(new MockLoggerProvider());
2323
});
2424
sc.AddBootstrapBlazorTcpSocketFactory();
25-
2625
var provider = sc.BuildServiceProvider();
2726
var factory = provider.GetRequiredService<ITcpSocketFactory>();
28-
var client1 = factory.GetOrCreate("localhost", 0);
27+
var client1 = factory.GetOrCreate("demo", "localhost", 0);
2928
client1.Close();
3029

31-
var client2 = factory.GetOrCreate("localhost", 0);
30+
var client2 = factory.GetOrCreate("demo", "localhost", 0);
3231
Assert.Equal(client1, client2);
3332

3433
var ip = Dns.GetHostAddresses(Dns.GetHostName(), AddressFamily.InterNetwork).FirstOrDefault() ?? IPAddress.Loopback;
35-
var client3 = factory.GetOrCreate(ip.ToString(), 0);
34+
var client3 = factory.GetOrCreate("demo1", ip.ToString(), 0);
3635

3736
// 测试不合格 IP 地址
38-
var client4 = factory.GetOrCreate("256.0.0.1", 0);
37+
var client4 = factory.GetOrCreate("demo2", "256.0.0.1", 0);
3938

40-
var client5 = factory.Remove("256.0.0.1", 0);
39+
var client5 = factory.Remove("demo2");
4140
Assert.Equal(client4, client5);
4241
Assert.NotNull(client5);
4342

@@ -451,7 +450,7 @@ private static ITcpSocketClient CreateClient()
451450
sc.AddBootstrapBlazorTcpSocketFactory();
452451
var provider = sc.BuildServiceProvider();
453452
var factory = provider.GetRequiredService<ITcpSocketFactory>();
454-
var client = factory.GetOrCreate("localhost", 0);
453+
var client = factory.GetOrCreate("test", "localhost", 0);
455454
return client;
456455
}
457456

test/UnitTest/Utils/UtilityTest.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,10 @@ public void ConvertToIpEndPoint_Ok()
758758
{
759759
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => Utility.ConvertToIpEndPoint("localhost", 88990));
760760
Assert.NotNull(ex);
761+
762+
ex = null;
763+
ex = Assert.Throws<ArgumentOutOfRangeException>(() => Utility.ConvertToIpEndPoint("localhost", -1000));
764+
Assert.NotNull(ex);
761765
}
762766

763767
[AutoGenerateClass(Align = Alignment.Center)]

0 commit comments

Comments
 (0)