2025-07-30 10:01:20 +00:00
|
|
|
|
//------------------------------------------------------------------------------
|
2024-10-14 19:06:09 +08:00
|
|
|
|
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
|
|
|
|
|
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
|
|
|
|
|
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
|
|
|
|
|
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
|
|
|
|
|
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
|
|
|
|
|
// 使用文档:https://thingsgateway.cn/
|
|
|
|
|
|
// QQ群:605534569
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
2025-02-06 12:08:40 +08:00
|
|
|
|
using ThingsGateway.NewLife;
|
|
|
|
|
|
|
2024-10-14 19:06:09 +08:00
|
|
|
|
namespace ThingsGateway.Foundation;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Udp通道
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class UdpSessionChannel : UdpSession, IClientChannel
|
|
|
|
|
|
{
|
2025-07-18 17:46:56 +08:00
|
|
|
|
private readonly WaitLock _connectLock = new WaitLock(nameof(UdpSessionChannel));
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public UdpSessionChannel(IChannelOptions channelOptions)
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
ChannelOptions = channelOptions;
|
2025-08-01 21:53:47 +08:00
|
|
|
|
ResetSign();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public override TouchSocketConfig Config => base.Config ?? ChannelOptions.Config;
|
2025-08-21 11:46:58 +00:00
|
|
|
|
private IDeviceDataHandleAdapter _deviceDataHandleAdapter;
|
|
|
|
|
|
public void SetDataHandlingAdapterLogger(ILog log)
|
|
|
|
|
|
{
|
2025-08-28 01:39:39 +08:00
|
|
|
|
if (_deviceDataHandleAdapter != DataHandlingAdapter && DataHandlingAdapter is IDeviceDataHandleAdapter handleAdapter)
|
2025-08-21 11:46:58 +00:00
|
|
|
|
{
|
|
|
|
|
|
_deviceDataHandleAdapter = handleAdapter;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (_deviceDataHandleAdapter != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_deviceDataHandleAdapter.Logger = log;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public void SetDataHandlingAdapter(DataHandlingAdapter adapter)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (adapter is UdpDataHandlingAdapter udpDataHandlingAdapter)
|
|
|
|
|
|
SetAdapter(udpDataHandlingAdapter);
|
|
|
|
|
|
if (adapter is IDeviceDataHandleAdapter deviceDataHandleAdapter)
|
|
|
|
|
|
_deviceDataHandleAdapter = deviceDataHandleAdapter;
|
|
|
|
|
|
}
|
2025-07-30 10:01:20 +00:00
|
|
|
|
public void ResetSign(int minSign = 0, int maxSign = ushort.MaxValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pool = WaitHandlePool;
|
|
|
|
|
|
WaitHandlePool = new WaitHandlePool<MessageBase>(minSign, maxSign);
|
|
|
|
|
|
pool?.CancelAll();
|
|
|
|
|
|
}
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-08-01 21:53:47 +08:00
|
|
|
|
public ChannelReceivedEventHandler ChannelReceived { get; } = new();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public IChannelOptions ChannelOptions { get; }
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public ChannelTypeEnum ChannelType => ChannelOptions.ChannelType;
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public ConcurrentList<IDevice> Collects { get; } = new();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public bool Online => ServerState == ServerState.Running;
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public DataHandlingAdapter ReadOnlyDataHandlingAdapter => DataHandlingAdapter;
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-08-01 21:53:47 +08:00
|
|
|
|
public ChannelEventHandler Started { get; } = new();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-08-01 21:53:47 +08:00
|
|
|
|
public ChannelEventHandler Starting { get; } = new();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-08-01 21:53:47 +08:00
|
|
|
|
public ChannelEventHandler Stoped { get; } = new();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
/// <inheritdoc/>
|
2025-08-01 21:53:47 +08:00
|
|
|
|
public ChannelEventHandler Stoping { get; } = new();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 等待池
|
|
|
|
|
|
/// </summary>
|
2025-08-21 11:46:58 +00:00
|
|
|
|
public WaitHandlePool<MessageBase> WaitHandlePool { get; set; } = new(0, ushort.MaxValue);
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-01-24 22:42:26 +08:00
|
|
|
|
public WaitLock WaitLock => ChannelOptions.WaitLock;
|
2025-03-12 23:14:23 +08:00
|
|
|
|
public virtual WaitLock GetLock(string key) => WaitLock;
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
2025-08-21 11:46:58 +00:00
|
|
|
|
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-04-26 15:02:57 +08:00
|
|
|
|
public Task<Result> CloseAsync(string msg, CancellationToken token)
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-04-26 15:02:57 +08:00
|
|
|
|
return StopAsync(token);
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-08-21 11:46:58 +00:00
|
|
|
|
public Task ConnectAsync(CancellationToken token = default)
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (token.IsCancellationRequested)
|
2025-08-21 11:46:58 +00:00
|
|
|
|
return EasyTask.CompletedTask; ;
|
|
|
|
|
|
return StartAsync();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-21 11:46:58 +00:00
|
|
|
|
|
2025-07-30 10:01:20 +00:00
|
|
|
|
public CancellationToken ClosedToken => this.m_transport == null ? new CancellationToken(true) : this.m_transport.Token;
|
|
|
|
|
|
private CancellationTokenSource m_transport;
|
2024-10-14 19:06:09 +08:00
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public override async Task StartAsync()
|
|
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
if (ServerState != ServerState.Running)
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
try
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-03-16 23:31:37 +08:00
|
|
|
|
await _connectLock.WaitAsync().ConfigureAwait(false);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
|
|
|
|
|
|
if (ServerState != ServerState.Running)
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
if (ServerState != ServerState.Stopped)
|
|
|
|
|
|
{
|
|
|
|
|
|
await base.StopAsync().ConfigureAwait(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
//await SetupAsync(Config.Clone()).ConfigureAwait(false);
|
2025-03-01 21:00:24 +08:00
|
|
|
|
await this.OnChannelEvent(Starting).ConfigureAwait(false);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
await base.StartAsync().ConfigureAwait(false);
|
|
|
|
|
|
if (ServerState == ServerState.Running)
|
|
|
|
|
|
{
|
2025-06-10 15:49:47 +08:00
|
|
|
|
Logger?.Info($"{Monitor.IPHost}{AppResource.ServiceStarted}");
|
2025-03-01 21:00:24 +08:00
|
|
|
|
await this.OnChannelEvent(Started).ConfigureAwait(false);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-24 22:42:26 +08:00
|
|
|
|
finally
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-07-30 10:01:20 +00:00
|
|
|
|
var cts = m_transport;
|
|
|
|
|
|
m_transport = new();
|
|
|
|
|
|
cts?.SafeCancel();
|
|
|
|
|
|
cts?.SafeDispose();
|
2025-03-16 23:31:37 +08:00
|
|
|
|
_connectLock.Release();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2025-04-26 15:02:57 +08:00
|
|
|
|
public override async Task<Result> StopAsync(CancellationToken token)
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (Monitor != null)
|
|
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-04-26 15:02:57 +08:00
|
|
|
|
await _connectLock.WaitAsync(token).ConfigureAwait(false);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
if (Monitor != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
await this.OnChannelEvent(Stoping).ConfigureAwait(false);
|
2025-04-26 15:02:57 +08:00
|
|
|
|
var result = await base.StopAsync(token).ConfigureAwait(false);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
if (Monitor == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
await this.OnChannelEvent(Stoped).ConfigureAwait(false);
|
2025-06-10 15:49:47 +08:00
|
|
|
|
Logger?.Info($"{AppResource.ServiceStoped}");
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2025-04-26 15:02:57 +08:00
|
|
|
|
return result;
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-04-26 15:02:57 +08:00
|
|
|
|
var result = await base.StopAsync(token).ConfigureAwait(false);
|
|
|
|
|
|
return result;
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
2024-10-14 19:06:09 +08:00
|
|
|
|
{
|
2025-07-30 10:01:20 +00:00
|
|
|
|
var cts = m_transport;
|
|
|
|
|
|
m_transport = null;
|
|
|
|
|
|
cts?.SafeCancel();
|
|
|
|
|
|
cts?.SafeDispose();
|
2025-03-16 23:31:37 +08:00
|
|
|
|
_connectLock.Release();
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-04-26 15:02:57 +08:00
|
|
|
|
var result = await base.StopAsync(token).ConfigureAwait(false);
|
|
|
|
|
|
return result;
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public override string? ToString()
|
|
|
|
|
|
{
|
2025-01-24 22:42:26 +08:00
|
|
|
|
return $"{ChannelOptions.BindUrl} {ChannelOptions.RemoteUrl}";
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
protected override async Task OnUdpReceived(UdpReceivedDataEventArgs e)
|
|
|
|
|
|
{
|
2025-09-08 17:56:19 +08:00
|
|
|
|
await base.OnUdpReceived(e).ConfigureAwait(false);
|
2025-01-24 22:42:26 +08:00
|
|
|
|
|
|
|
|
|
|
if (e.Handled)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2025-09-08 17:56:19 +08:00
|
|
|
|
await this.OnChannelReceivedEvent(e, ChannelReceived).ConfigureAwait(false);
|
2025-08-28 14:21:58 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
}
|
2024-10-14 19:06:09 +08:00
|
|
|
|
|
2025-01-24 22:42:26 +08:00
|
|
|
|
/// <inheritdoc/>
|
2025-07-30 10:01:20 +00:00
|
|
|
|
protected override void SafetyDispose(bool disposing)
|
2025-01-24 22:42:26 +08:00
|
|
|
|
{
|
2025-08-01 16:36:27 +08:00
|
|
|
|
m_transport?.SafeCancel();
|
2025-07-30 10:01:20 +00:00
|
|
|
|
m_transport?.SafeDispose();
|
2025-08-21 11:46:58 +00:00
|
|
|
|
m_transport = null;
|
|
|
|
|
|
WaitHandlePool?.CancelAll();
|
2025-07-30 10:01:20 +00:00
|
|
|
|
base.SafetyDispose(disposing);
|
2024-10-14 19:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|