Skip to content

Commit c262bf4

Browse files
committed
feat: 使用 SemaphoreSlim 信号量控制重连并发逻辑
1 parent a9bfbfb commit c262bf4

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

src/BootstrapBlazor/Services/TcpSocket/TcpSocketClientBase.cs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,7 @@ public abstract class TcpSocketClientBase(SocketClientOptions options) : ITcpSoc
6565
private CancellationTokenSource? _receiveCancellationTokenSource;
6666
private CancellationTokenSource? _autoConnectTokenSource;
6767

68-
#if NET9_0_OR_GREATER
69-
private readonly Lock _lock = new();
70-
#else
71-
private readonly object _lock = new();
72-
#endif
68+
private readonly SemaphoreSlim _semaphoreSlim = new(1, 1);
7369

7470
/// <summary>
7571
/// <inheritdoc/>
@@ -84,12 +80,22 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
8480
return true;
8581
}
8682

87-
lock (_lock)
83+
var connectionToken = GenerateConnectionToken(token);
84+
try
8885
{
89-
if (IsConnected)
90-
{
91-
return true;
92-
}
86+
await _semaphoreSlim.WaitAsync(connectionToken).ConfigureAwait(false);
87+
}
88+
catch (OperationCanceledException)
89+
{
90+
// 如果信号量等待被取消,则直接返回 IsConnected
91+
// 不管是超时还是被取消,都不需要重连,肯定有其他线程在连接中
92+
return IsConnected;
93+
}
94+
95+
if (IsConnected)
96+
{
97+
_semaphoreSlim.Release();
98+
return true;
9399
}
94100

95101
var reconnect = true;
@@ -99,7 +105,7 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
99105

100106
try
101107
{
102-
ret = await ConnectCoreAsync(SocketClientProvider, endPoint, token);
108+
ret = await ConnectCoreAsync(SocketClientProvider, endPoint, connectionToken);
103109
}
104110
catch (OperationCanceledException ex)
105111
{
@@ -118,10 +124,14 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
118124
Log(LogLevel.Error, ex, $"TCP Socket connection failed from {LocalEndPoint} to {endPoint}");
119125
}
120126

127+
// 释放信号量
128+
_semaphoreSlim.Release();
129+
121130
if (!ret && reconnect)
122131
{
123132
Reconnect();
124133
}
134+
125135
return ret;
126136
}
127137

@@ -153,14 +163,7 @@ private async ValueTask<bool> ConnectCoreAsync(ISocketClientProvider provider, I
153163
_localEndPoint = Options.LocalEndPoint;
154164
_remoteEndPoint = endPoint;
155165

156-
var connectionToken = token;
157-
if (Options.ConnectTimeout > 0)
158-
{
159-
// 设置连接超时时间
160-
var connectTokenSource = new CancellationTokenSource(options.ConnectTimeout);
161-
connectionToken = CancellationTokenSource.CreateLinkedTokenSource(token, connectTokenSource.Token).Token;
162-
}
163-
var ret = await provider.ConnectAsync(endPoint, connectionToken);
166+
var ret = await provider.ConnectAsync(endPoint, token);
164167

165168
if (ret)
166169
{
@@ -174,6 +177,18 @@ private async ValueTask<bool> ConnectCoreAsync(ISocketClientProvider provider, I
174177
return ret;
175178
}
176179

180+
private CancellationToken GenerateConnectionToken(CancellationToken token)
181+
{
182+
var connectionToken = token;
183+
if (Options.ConnectTimeout > 0)
184+
{
185+
// 设置连接超时时间
186+
var connectTokenSource = new CancellationTokenSource(options.ConnectTimeout);
187+
connectionToken = CancellationTokenSource.CreateLinkedTokenSource(token, connectTokenSource.Token).Token;
188+
}
189+
return connectionToken;
190+
}
191+
177192
/// <summary>
178193
/// <inheritdoc/>
179194
/// </summary>

0 commit comments

Comments
 (0)