Skip to content

Commit b72ddfc

Browse files
committed
Revert "refactor: 移除 ReceiveAsync 方法"
This reverts commit 6cba73e.
1 parent 6cba73e commit b72ddfc

File tree

3 files changed

+100
-82
lines changed

3 files changed

+100
-82
lines changed

src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ public interface ITcpSocketClient : IAsyncDisposable
6262
/// sent successfully; otherwise, <see langword="false"/>.</returns>
6363
ValueTask<bool> SendAsync(ReadOnlyMemory<byte> data, CancellationToken token = default);
6464

65+
/// <summary>
66+
/// Asynchronously receives a block of data from the underlying source.
67+
/// </summary>
68+
/// <remarks>This method is non-blocking and completes when data is available or the operation is
69+
/// canceled. If the operation is canceled, the returned task will be in a faulted state with a <see
70+
/// cref="OperationCanceledException"/>.</remarks>
71+
/// <param name="token">A cancellation token that can be used to cancel the operation. The default value is <see langword="default"/>.</param>
72+
/// <returns>A <see cref="ValueTask{TResult}"/> containing a <see cref="Memory{T}"/> of bytes representing the received data.
73+
/// The returned memory may be empty if no data is available.</returns>
74+
ValueTask<Memory<byte>> ReceiveAsync(CancellationToken token = default);
75+
6576
/// <summary>
6677
/// Closes the current connection or resource, releasing any associated resources.
6778
/// </summary>

src/BootstrapBlazor/Services/TcpSocket/TcpSocketClientBase.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,29 @@ public virtual async ValueTask<bool> SendAsync(ReadOnlyMemory<byte> data, Cancel
164164
return ret;
165165
}
166166

167+
/// <summary>
168+
/// <inheritdoc/>
169+
/// </summary>
170+
/// <param name="token"></param>
171+
/// <returns></returns>
172+
public virtual async ValueTask<Memory<byte>> ReceiveAsync(CancellationToken token = default)
173+
{
174+
if (SocketClientProvider is not { IsConnected: true })
175+
{
176+
throw new InvalidOperationException($"TCP Socket is not connected {LocalEndPoint}");
177+
}
178+
179+
if (options.IsAutoReceive)
180+
{
181+
throw new InvalidOperationException("Cannot call ReceiveAsync when IsAutoReceive is true. Use the auto-receive mechanism instead.");
182+
}
183+
184+
using var block = MemoryPool<byte>.Shared.Rent(options.ReceiveBufferSize);
185+
var buffer = block.Memory;
186+
var len = await ReceiveCoreAsync(SocketClientProvider, buffer, token);
187+
return buffer[..len];
188+
}
189+
167190
private async ValueTask AutoReceiveAsync()
168191
{
169192
// 自动接收方法

test/UnitTest/Services/TcpSocketFactoryTest.cs

Lines changed: 66 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -142,22 +142,6 @@ public async Task SendAsync_Error()
142142
await client.SendAsync(data);
143143
}
144144

145-
[Fact]
146-
public async Task SendAsync_Ok()
147-
{
148-
var port = 8880;
149-
var server = StartTcpServer(port, MockSplitPackageAsync);
150-
151-
// 创建客户端
152-
var client = CreateClient();
153-
154-
// 连接 TCP Server
155-
await client.ConnectAsync("localhost", port);
156-
157-
// 内部生成异常日志
158-
await client.SendAsync(new byte[] { 0x1, 0x2 });
159-
}
160-
161145
[Fact]
162146
public async Task SendAsync_Cancel()
163147
{
@@ -225,92 +209,92 @@ public async Task ReceiveAsync_Cancel()
225209
await Task.Delay(50);
226210
}
227211

228-
//[Fact]
229-
//public async Task ReceiveAsync_InvalidOperationException()
230-
//{
231-
// // 未连接时调用 ReceiveAsync 方法会抛出 InvalidOperationException 异常
232-
// var client = CreateClient();
233-
// var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await client.ReceiveAsync());
234-
// Assert.NotNull(ex);
212+
[Fact]
213+
public async Task ReceiveAsync_InvalidOperationException()
214+
{
215+
// 未连接时调用 ReceiveAsync 方法会抛出 InvalidOperationException 异常
216+
var client = CreateClient();
217+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await client.ReceiveAsync());
218+
Assert.NotNull(ex);
235219

236-
// // 已连接但是启用了自动接收功能时调用 ReceiveAsync 方法会抛出 InvalidOperationException 异常
237-
// var port = 8893;
238-
// var server = StartTcpServer(port, MockSplitPackageAsync);
220+
// 已连接但是启用了自动接收功能时调用 ReceiveAsync 方法会抛出 InvalidOperationException 异常
221+
var port = 8893;
222+
var server = StartTcpServer(port, MockSplitPackageAsync);
239223

240-
// client.Options.IsAutoReceive = true;
241-
// var connected = await client.ConnectAsync("localhost", port);
242-
// Assert.True(connected);
224+
client.Options.IsAutoReceive = true;
225+
var connected = await client.ConnectAsync("localhost", port);
226+
Assert.True(connected);
243227

244-
// ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await client.ReceiveAsync());
245-
// Assert.NotNull(ex);
246-
//}
228+
ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await client.ReceiveAsync());
229+
Assert.NotNull(ex);
230+
}
247231

248-
//[Fact]
249-
//public async Task ReceiveAsync_Ok()
250-
//{
251-
// var port = 8891;
252-
// var server = StartTcpServer(port, MockSplitPackageAsync);
232+
[Fact]
233+
public async Task ReceiveAsync_Ok()
234+
{
235+
var port = 8891;
236+
var server = StartTcpServer(port, MockSplitPackageAsync);
253237

254-
// var client = CreateClient();
255-
// client.Options.IsAutoReceive = false;
256-
// var connected = await client.ConnectAsync("localhost", port);
257-
// Assert.True(connected);
238+
var client = CreateClient();
239+
client.Options.IsAutoReceive = false;
240+
var connected = await client.ConnectAsync("localhost", port);
241+
Assert.True(connected);
258242

259-
// var data = new ReadOnlyMemory<byte>([1, 2, 3, 4, 5]);
260-
// var send = await client.SendAsync(data);
261-
// Assert.True(send);
243+
var data = new ReadOnlyMemory<byte>([1, 2, 3, 4, 5]);
244+
var send = await client.SendAsync(data);
245+
Assert.True(send);
262246

263-
// var payload = await client.ReceiveAsync();
264-
// Assert.Equal(payload.ToArray(), [1, 2, 3, 4, 5]);
265-
//}
247+
var payload = await client.ReceiveAsync();
248+
Assert.Equal(payload.ToArray(), [1, 2, 3, 4, 5]);
249+
}
266250

267-
//[Fact]
268-
//public async Task ReceiveAsync_Error()
269-
//{
270-
// var client = CreateClient();
251+
[Fact]
252+
public async Task ReceiveAsync_Error()
253+
{
254+
var client = CreateClient();
271255

272-
// // 测试未建立连接前调用 ReceiveAsync 方法报异常逻辑
273-
// var baseType = client.GetType().BaseType;
274-
// Assert.NotNull(baseType);
256+
// 测试未建立连接前调用 ReceiveAsync 方法报异常逻辑
257+
var baseType = client.GetType().BaseType;
258+
Assert.NotNull(baseType);
275259

276-
// var methodInfo = baseType.GetMethod("AutoReceiveAsync", BindingFlags.NonPublic | BindingFlags.Instance);
277-
// Assert.NotNull(methodInfo);
260+
var methodInfo = baseType.GetMethod("AutoReceiveAsync", BindingFlags.NonPublic | BindingFlags.Instance);
261+
Assert.NotNull(methodInfo);
278262

279-
// var task = (ValueTask)methodInfo.Invoke(client, null)!;
280-
// var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await task);
281-
// Assert.NotNull(ex);
263+
var task = (ValueTask)methodInfo.Invoke(client, null)!;
264+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await task);
265+
Assert.NotNull(ex);
282266

283-
// var port = 8882;
284-
// var server = StartTcpServer(port, MockSplitPackageAsync);
267+
var port = 8882;
268+
var server = StartTcpServer(port, MockSplitPackageAsync);
285269

286-
// Assert.Equal(1024 * 64, client.Options.ReceiveBufferSize);
270+
Assert.Equal(1024 * 64, client.Options.ReceiveBufferSize);
287271

288-
// client.Options.ReceiveBufferSize = 1024 * 20;
289-
// Assert.Equal(1024 * 20, client.Options.ReceiveBufferSize);
272+
client.Options.ReceiveBufferSize = 1024 * 20;
273+
Assert.Equal(1024 * 20, client.Options.ReceiveBufferSize);
290274

291-
// ReadOnlyMemory<byte> buffer = ReadOnlyMemory<byte>.Empty;
292-
// var tcs = new TaskCompletionSource();
275+
ReadOnlyMemory<byte> buffer = ReadOnlyMemory<byte>.Empty;
276+
var tcs = new TaskCompletionSource();
293277

294-
// // 增加接收回调方法
295-
// client.ReceivedCallBack = b =>
296-
// {
297-
// buffer = b;
298-
// tcs.SetResult();
299-
// return ValueTask.CompletedTask;
300-
// };
278+
// 增加接收回调方法
279+
client.ReceivedCallBack = b =>
280+
{
281+
buffer = b;
282+
tcs.SetResult();
283+
return ValueTask.CompletedTask;
284+
};
301285

302-
// await client.ConnectAsync("localhost", port);
286+
await client.ConnectAsync("localhost", port);
303287

304-
// // 发送数据导致接收数据异常
305-
// var data = new ReadOnlyMemory<byte>([1, 2, 3, 4, 5]);
306-
// await client.SendAsync(data);
288+
// 发送数据导致接收数据异常
289+
var data = new ReadOnlyMemory<byte>([1, 2, 3, 4, 5]);
290+
await client.SendAsync(data);
307291

308-
// await tcs.Task;
309-
// Assert.Equal(buffer.ToArray(), [1, 2, 3, 4, 5]);
292+
await tcs.Task;
293+
Assert.Equal(buffer.ToArray(), [1, 2, 3, 4, 5]);
310294

311-
// // 关闭连接
312-
// StopTcpServer(server);
313-
//}
295+
// 关闭连接
296+
StopTcpServer(server);
297+
}
314298

315299
[Fact]
316300
public async Task FixLengthDataPackageHandler_Ok()

0 commit comments

Comments
 (0)