Skip to content

Commit 3016e14

Browse files
committed
wip: 重构实现方法(未完成)
1 parent b310fed commit 3016e14

3 files changed

Lines changed: 194 additions & 150 deletions

File tree

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
using Microsoft.Extensions.Logging;
6+
using System.Buffers;
7+
using System.Net;
8+
using TouchSocket.Core;
9+
using TouchSocket.Sockets;
10+
11+
namespace BootstrapBlazor.Components;
12+
13+
sealed class DefaultTcpSocketClient(IPEndPoint endPoint) : ITcpSocketClient
14+
{
15+
private TcpClient? _client;
16+
private IDataPackageHandler? _dataPackageHandler;
17+
private CancellationTokenSource? _receiveCancellationTokenSource;
18+
private IPEndPoint? _remoteEndPoint;
19+
20+
public bool IsConnected => _client?.Online ?? false;
21+
22+
public IPEndPoint LocalEndPoint { get; set; } = endPoint;
23+
24+
[NotNull]
25+
public ILogger<DefaultTcpSocketClient>? Logger { get; set; }
26+
27+
public int ReceiveBufferSize { get; set; } = 1024 * 10;
28+
29+
public Func<ReadOnlyMemory<byte>, ValueTask>? ReceivedCallBack { get; set; }
30+
31+
public void SetDataHandler(IDataPackageHandler handler)
32+
{
33+
_dataPackageHandler = handler;
34+
}
35+
36+
public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken token = default)
37+
{
38+
var ret = false;
39+
try
40+
{
41+
// 释放资源
42+
Close();
43+
44+
// 创建新的 TouchSocket TcpClient 实例
45+
_client ??= new TcpClient();
46+
await _client.SetupAsync(new TouchSocketConfig().SetBindIPHost(new IPHost(LocalEndPoint.Address, LocalEndPoint.Port)));
47+
48+
await _client.ConnectAsync(new IPHost(endPoint.Address, endPoint.Port), );
49+
50+
// 开始接收数据
51+
//_ = Task.Run(ReceiveAsync, token);
52+
53+
//LocalEndPoint = (IPEndPoint)_client.Client.LocalEndPoint!;
54+
_remoteEndPoint = endPoint;
55+
ret = true;
56+
}
57+
catch (OperationCanceledException ex)
58+
{
59+
Logger.LogWarning(ex, "TCP Socket connect operation was canceled from {LocalEndPoint} to {RemoteEndPoint}", LocalEndPoint, endPoint);
60+
}
61+
catch (Exception ex)
62+
{
63+
Logger.LogError(ex, "TCP Socket connection failed from {LocalEndPoint} to {RemoteEndPoint}", LocalEndPoint, endPoint);
64+
}
65+
return ret;
66+
}
67+
68+
public async ValueTask<bool> SendAsync(ReadOnlyMemory<byte> data, CancellationToken token = default)
69+
{
70+
if (_client is not { Online: true })
71+
{
72+
throw new InvalidOperationException($"TCP Socket is not connected {LocalEndPoint}");
73+
}
74+
75+
var ret = false;
76+
try
77+
{
78+
if (_dataPackageHandler != null)
79+
{
80+
data = await _dataPackageHandler.SendAsync(data);
81+
}
82+
//var stream = _client.GetStream();
83+
//await stream.WriteAsync(data, token);
84+
ret = true;
85+
}
86+
catch (OperationCanceledException ex)
87+
{
88+
Logger.LogWarning(ex, "TCP Socket send operation was canceled from {LocalEndPoint} to {RemoteEndPoint}", LocalEndPoint, _remoteEndPoint);
89+
}
90+
catch (Exception ex)
91+
{
92+
Logger.LogError(ex, "TCP Socket send failed from {LocalEndPoint} to {RemoteEndPoint}", LocalEndPoint, _remoteEndPoint);
93+
}
94+
return ret;
95+
}
96+
97+
private async ValueTask ReceiveAsync()
98+
{
99+
_receiveCancellationTokenSource ??= new();
100+
while (_receiveCancellationTokenSource is { IsCancellationRequested: false })
101+
{
102+
if (_client is not { Online: true })
103+
{
104+
throw new InvalidOperationException($"TCP Socket is not connected {LocalEndPoint}");
105+
}
106+
107+
try
108+
{
109+
using var block = MemoryPool<byte>.Shared.Rent(ReceiveBufferSize);
110+
var buffer = block.Memory;
111+
//var stream = _client.GetStream();
112+
//var len = await stream.ReadAsync(buffer, _receiveCancellationTokenSource.Token);
113+
//if (len == 0)
114+
//{
115+
// // 远端主机关闭链路
116+
// Logger.LogInformation("TCP Socket {LocalEndPoint} received 0 data closed by {RemoteEndPoint}", LocalEndPoint, _remoteEndPoint);
117+
// break;
118+
//}
119+
//else
120+
//{
121+
// buffer = buffer[..len];
122+
123+
// if (ReceivedCallBack != null)
124+
// {
125+
// await ReceivedCallBack(buffer);
126+
// }
127+
128+
// if (_dataPackageHandler != null)
129+
// {
130+
// await _dataPackageHandler.ReceiveAsync(buffer);
131+
// }
132+
//}
133+
}
134+
catch (OperationCanceledException ex)
135+
{
136+
Logger.LogWarning(ex, "TCP Socket receive operation was canceled from {LocalEndPoint} to {RemoteEndPoint}", LocalEndPoint, _remoteEndPoint);
137+
}
138+
catch (Exception ex)
139+
{
140+
Logger.LogError(ex, "TCP Socket receive failed from {LocalEndPoint} to {RemoteEndPoint}", LocalEndPoint, _remoteEndPoint);
141+
}
142+
}
143+
}
144+
145+
public void Close()
146+
{
147+
Dispose(true);
148+
}
149+
150+
private void Dispose(bool disposing)
151+
{
152+
if (disposing)
153+
{
154+
_remoteEndPoint = null;
155+
156+
// 取消接收数据的任务
157+
if (_receiveCancellationTokenSource is not null)
158+
{
159+
_receiveCancellationTokenSource.Cancel();
160+
_receiveCancellationTokenSource.Dispose();
161+
_receiveCancellationTokenSource = null;
162+
}
163+
164+
// 释放 TcpClient 资源
165+
if (_client != null)
166+
{
167+
_client.CloseAsync();
168+
_client = null;
169+
}
170+
}
171+
}
172+
173+
/// <summary>
174+
/// <inheritdoc/>
175+
/// </summary>
176+
public void Dispose()
177+
{
178+
Dispose(true);
179+
GC.SuppressFinalize(this);
180+
}
181+
}

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,33 @@
55
using Microsoft.Extensions.DependencyInjection;
66
using Microsoft.Extensions.Logging;
77
using System.Collections.Concurrent;
8+
using System.Net;
9+
using System.Runtime.Versioning;
810

911
namespace BootstrapBlazor.Components;
1012

11-
class DefaultTcpSocketFactory : ITcpSocketFactory
13+
[UnsupportedOSPlatform("browser")]
14+
sealed class DefaultTcpSocketFactory(IServiceProvider provider) : ITcpSocketFactory
1215
{
1316
private readonly ConcurrentDictionary<string, ITcpSocketClient> _pool = new();
1417

15-
public ITcpSocketClient GetOrCreate(string host, int port = 0)
18+
public ITcpSocketClient GetOrCreate(string name, Func<string, IPEndPoint> valueFactory)
1619
{
17-
return _pool.GetOrAdd($"{host}:{port}", key =>
20+
return _pool.GetOrAdd(name, key =>
1821
{
19-
var client = new TouchSocketTcpClient();
22+
var endPoint = valueFactory(key);
23+
var client = new DefaultTcpSocketClient(endPoint)
24+
{
25+
Logger = provider.GetService<ILogger<DefaultTcpSocketClient>>()
26+
};
2027
return client;
2128
});
2229
}
2330

24-
public ITcpSocketClient? Remove(string host, int port)
31+
public ITcpSocketClient? Remove(string name)
2532
{
2633
ITcpSocketClient? client = null;
27-
if (_pool.TryRemove($"{host}:{port}", out var c))
34+
if (_pool.TryRemove(name, out var c))
2835
{
2936
client = c;
3037
}

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

Lines changed: 0 additions & 144 deletions
This file was deleted.

0 commit comments

Comments
 (0)