Skip to content

Commit d691979

Browse files
committed
重构(tcp): 更新TouchSocket版本并优化连接逻辑
在 `BootstrapBlazor.TouchSocket.csproj` 文件中,将 `TouchSocket` 的版本从 `3.1.11.8` 更新为 `4.0.0-Alpha.10`。 在 `DefaultTcpSocketProvider.cs` 文件中,类的访问修饰符从 `sealed` 改为 `internal`,并添加了对 `System.Diagnostics` 的引用。 修改 `IsConnected` 属性的实现,确保调用基类的 `Online` 属性。 添加新的 `CloseAsync` 方法,重写连接逻辑以包含异常处理,并在连接成功后进行调试断言。 更新 `ReceiveAsync` 方法的数据读取逻辑,使用基类的 `Transport.Input` 进行数据读取,并确保正确处理数据缓冲区。 重写 `SendAsync` 方法,添加对取消令牌的处理,并确保在发送数据时正确管理锁。 重写 `ReceiveLoopAsync` 方法,注释说明新的接收循环逻辑,确保数据通过管道直接读取,而不进行额外的数据读取操作
1 parent 1a64858 commit d691979

2 files changed

Lines changed: 67 additions & 28 deletions

File tree

src/extensions/BootstrapBlazor.TouchSocket/BootstrapBlazor.TouchSocket.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17-
<PackageReference Include="TouchSocket" Version="3.1.11.8" />
17+
<PackageReference Include="TouchSocket" Version="4.0.0-Alpha.10" />
1818
</ItemGroup>
1919

2020
<ItemGroup>

src/extensions/BootstrapBlazor.TouchSocket/Services/DefaultTcpSocketProvider.cs

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,34 @@
33
// Website: https://www.blazor.zone or https://argozhang.github.io/
44

55
using System.Buffers;
6+
using System.Diagnostics;
67
using System.IO.Pipelines;
78
using System.Net;
89
using TouchSocket.Core;
910
using TouchSocket.Sockets;
1011

1112
namespace BootstrapBlazor.Components;
1213

13-
sealed class DefaultTcpSocketProvider : TcpClientBase, ISocketClientProvider
14+
internal sealed class DefaultTcpSocketProvider : TcpClientBase, ISocketClientProvider
1415
{
15-
private readonly Pipe _pipe = new();
16-
1716
/// <summary>
1817
/// <inheritdoc/>
1918
/// </summary>
20-
public bool IsConnected => Online;
19+
public bool IsConnected => base.Online;
2120

2221
/// <summary>
2322
/// <inheritdoc/>
2423
/// </summary>
2524
public IPEndPoint LocalEndPoint { get; set; } = new IPEndPoint(IPAddress.Any, 0);
2625

26+
/// <summary>
27+
/// <inheritdoc/>
28+
/// </summary>
29+
public async ValueTask CloseAsync()
30+
{
31+
await base.CloseAsync(string.Empty);
32+
}
33+
2734
/// <summary>
2835
/// <inheritdoc/>
2936
/// </summary>
@@ -32,53 +39,85 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
3239
await SetupAsync(new TouchSocketConfig()
3340
.SetBindIPHost(new IPHost(LocalEndPoint.Address, LocalEndPoint.Port))
3441
.SetRemoteIPHost(new IPHost(endPoint.Address, endPoint.Port)));
35-
await TcpConnectAsync(int.MaxValue, token);
36-
if (Online)
42+
43+
try
3744
{
45+
await TcpConnectAsync(int.MaxValue, token);
46+
Debug.Assert(MainSocket != null, "MainSocket cannot be null after connection.");
47+
Debug.Assert(base.Online, "Online should be true after successful connection.");
3848
if (MainSocket.LocalEndPoint is IPEndPoint localEndPoint)
3949
{
4050
LocalEndPoint = localEndPoint;
4151
}
52+
return true;
53+
}
54+
catch (Exception ex)
55+
{
56+
this.Logger?.Exception(this, ex);
57+
return false;
4258
}
43-
return Online;
44-
}
45-
46-
/// <summary>
47-
/// <inheritdoc/>
48-
/// </summary>
49-
public async ValueTask<bool> SendAsync(ReadOnlyMemory<byte> data, CancellationToken token = default)
50-
{
51-
await ProtectedDefaultSendAsync(data, token);
52-
return true;
5359
}
5460

5561
/// <summary>
5662
/// <inheritdoc/>
5763
/// </summary>
5864
public async ValueTask<int> ReceiveAsync(Memory<byte> buffer, CancellationToken token = default)
5965
{
60-
var result = await _pipe.Reader.ReadAsync(token);
66+
token.ThrowIfCancellationRequested();
67+
this.ThrowIfTcpClientNotConnected();
68+
this.ThrowIfDisposed();
69+
70+
var result = await base.Transport.Input.ReadAsync(token);
6171
if (result.IsCompleted)
6272
{
6373
return 0;
6474
}
75+
var length = (int)Math.Min(result.Buffer.Length, buffer.Length);
6576

66-
result.Buffer.CopyTo(buffer.Span);
67-
return (int)result.Buffer.Length;
68-
}
77+
var sequence = result.Buffer.Slice(0, length);
6978

70-
protected override async ValueTask<bool> OnTcpReceiving(ByteBlock byteBlock)
71-
{
72-
await _pipe.Writer.WriteAsync(byteBlock.Memory);
73-
await _pipe.Writer.FlushAsync();
74-
return true;
79+
sequence.CopyTo(buffer.Span);
80+
base.Transport.Input.AdvanceTo(sequence.End);
81+
return length;
7582
}
7683

7784
/// <summary>
7885
/// <inheritdoc/>
7986
/// </summary>
80-
public async ValueTask CloseAsync()
87+
public async ValueTask<bool> SendAsync(ReadOnlyMemory<byte> data, CancellationToken token = default)
88+
{
89+
token.ThrowIfCancellationRequested();
90+
base.ThrowIfTcpClientNotConnected();
91+
base.ThrowIfDisposed();
92+
var pipeWriter = base.Transport.Output;
93+
var locker = base.Transport.SemaphoreSlimForWriter;
94+
await locker.WaitAsync(token);
95+
try
96+
{
97+
pipeWriter.Write(data.Span);
98+
var result = await pipeWriter.FlushAsync(token);
99+
if (result.IsCanceled || result.IsCompleted)
100+
{
101+
return false;
102+
}
103+
return true;
104+
}
105+
catch (Exception ex)
106+
{
107+
this.Logger?.Exception(this, ex);
108+
return false;
109+
}
110+
finally
111+
{
112+
locker.Release();
113+
}
114+
}
115+
116+
protected override sealed async Task ReceiveLoopAsync(ITransport transport)
81117
{
82-
await CloseAsync(string.Empty);
118+
//重写接收循环方法
119+
//此处不做任何数据读取
120+
//让数据直接到ReceiveAsync使用管道直接读取数据
121+
await Task.Delay(-1, transport.ClosedToken);
83122
}
84123
}

0 commit comments

Comments
 (0)