mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 10:50:48 +08:00
218 lines
7.0 KiB
C#
218 lines
7.0 KiB
C#
//------------------------------------------------------------------------------
|
||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||
// 使用文档:https://thingsgateway.cn/
|
||
// QQ群:605534569
|
||
//------------------------------------------------------------------------------
|
||
|
||
using ThingsGateway.NewLife;
|
||
|
||
namespace ThingsGateway.Foundation;
|
||
|
||
/// <summary>
|
||
/// Udp通道
|
||
/// </summary>
|
||
public class UdpSessionChannel : UdpSession, IClientChannel
|
||
{
|
||
private readonly WaitLock _connectLock = new WaitLock(nameof(UdpSessionChannel));
|
||
|
||
/// <inheritdoc/>
|
||
public UdpSessionChannel(IChannelOptions channelOptions)
|
||
{
|
||
ChannelOptions = channelOptions;
|
||
ResetSign();
|
||
}
|
||
public override TouchSocketConfig Config => base.Config ?? ChannelOptions.Config;
|
||
private IDeviceDataHandleAdapter _deviceDataHandleAdapter;
|
||
public void SetDataHandlingAdapterLogger(ILog log)
|
||
{
|
||
if (_deviceDataHandleAdapter != DataHandlingAdapter && DataHandlingAdapter is IDeviceDataHandleAdapter handleAdapter)
|
||
{
|
||
_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;
|
||
}
|
||
public void ResetSign(int minSign = 0, int maxSign = ushort.MaxValue)
|
||
{
|
||
var pool = WaitHandlePool;
|
||
WaitHandlePool = new WaitHandlePool<MessageBase>(minSign, maxSign);
|
||
pool?.CancelAll();
|
||
}
|
||
|
||
/// <inheritdoc/>
|
||
public ChannelReceivedEventHandler ChannelReceived { get; } = new();
|
||
|
||
/// <inheritdoc/>
|
||
public IChannelOptions ChannelOptions { get; }
|
||
|
||
/// <inheritdoc/>
|
||
public ChannelTypeEnum ChannelType => ChannelOptions.ChannelType;
|
||
|
||
/// <inheritdoc/>
|
||
public ConcurrentList<IDevice> Collects { get; } = new();
|
||
|
||
/// <inheritdoc/>
|
||
public bool Online => ServerState == ServerState.Running;
|
||
|
||
/// <inheritdoc/>
|
||
public DataHandlingAdapter ReadOnlyDataHandlingAdapter => DataHandlingAdapter;
|
||
|
||
/// <inheritdoc/>
|
||
public ChannelEventHandler Started { get; } = new();
|
||
|
||
/// <inheritdoc/>
|
||
public ChannelEventHandler Starting { get; } = new();
|
||
|
||
/// <inheritdoc/>
|
||
public ChannelEventHandler Stoped { get; } = new();
|
||
/// <inheritdoc/>
|
||
public ChannelEventHandler Stoping { get; } = new();
|
||
|
||
/// <summary>
|
||
/// 等待池
|
||
/// </summary>
|
||
public WaitHandlePool<MessageBase> WaitHandlePool { get; set; } = new(0, ushort.MaxValue);
|
||
|
||
/// <inheritdoc/>
|
||
public WaitLock WaitLock => ChannelOptions.WaitLock;
|
||
public virtual WaitLock GetLock(string key) => WaitLock;
|
||
|
||
|
||
|
||
/// <inheritdoc/>
|
||
public Task<Result> CloseAsync(string msg, CancellationToken token)
|
||
{
|
||
return StopAsync(token);
|
||
}
|
||
|
||
/// <inheritdoc/>
|
||
public Task ConnectAsync(CancellationToken token = default)
|
||
{
|
||
if (token.IsCancellationRequested)
|
||
return EasyTask.CompletedTask; ;
|
||
return StartAsync();
|
||
}
|
||
|
||
|
||
public CancellationToken ClosedToken => this.m_transport == null ? new CancellationToken(true) : this.m_transport.Token;
|
||
private CancellationTokenSource m_transport;
|
||
/// <inheritdoc/>
|
||
public override async Task StartAsync()
|
||
{
|
||
if (ServerState != ServerState.Running)
|
||
{
|
||
try
|
||
{
|
||
await _connectLock.WaitAsync().ConfigureAwait(false);
|
||
|
||
if (ServerState != ServerState.Running)
|
||
{
|
||
if (ServerState != ServerState.Stopped)
|
||
{
|
||
await base.StopAsync().ConfigureAwait(false);
|
||
}
|
||
//await SetupAsync(Config.Clone()).ConfigureAwait(false);
|
||
await this.OnChannelEvent(Starting).ConfigureAwait(false);
|
||
await base.StartAsync().ConfigureAwait(false);
|
||
if (ServerState == ServerState.Running)
|
||
{
|
||
Logger?.Info($"{Monitor.IPHost}{AppResource.ServiceStarted}");
|
||
await this.OnChannelEvent(Started).ConfigureAwait(false);
|
||
}
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
var cts = m_transport;
|
||
m_transport = new();
|
||
cts?.SafeCancel();
|
||
cts?.SafeDispose();
|
||
_connectLock.Release();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc/>
|
||
public override async Task<Result> StopAsync(CancellationToken token)
|
||
{
|
||
if (Monitor != null)
|
||
{
|
||
try
|
||
{
|
||
await _connectLock.WaitAsync(token).ConfigureAwait(false);
|
||
if (Monitor != null)
|
||
{
|
||
await this.OnChannelEvent(Stoping).ConfigureAwait(false);
|
||
var result = await base.StopAsync(token).ConfigureAwait(false);
|
||
if (Monitor == null)
|
||
{
|
||
await this.OnChannelEvent(Stoped).ConfigureAwait(false);
|
||
Logger?.Info($"{AppResource.ServiceStoped}");
|
||
}
|
||
return result;
|
||
}
|
||
else
|
||
{
|
||
var result = await base.StopAsync(token).ConfigureAwait(false);
|
||
return result;
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
var cts = m_transport;
|
||
m_transport = null;
|
||
cts?.SafeCancel();
|
||
cts?.SafeDispose();
|
||
_connectLock.Release();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var result = await base.StopAsync(token).ConfigureAwait(false);
|
||
return result;
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc/>
|
||
public override string? ToString()
|
||
{
|
||
return $"{ChannelOptions.BindUrl} {ChannelOptions.RemoteUrl}";
|
||
}
|
||
|
||
/// <inheritdoc/>
|
||
protected override async Task OnUdpReceived(UdpReceivedDataEventArgs e)
|
||
{
|
||
await base.OnUdpReceived(e).ConfigureAwait(false);
|
||
|
||
if (e.Handled)
|
||
return;
|
||
|
||
await this.OnChannelReceivedEvent(e, ChannelReceived).ConfigureAwait(false);
|
||
|
||
}
|
||
|
||
/// <inheritdoc/>
|
||
protected override void SafetyDispose(bool disposing)
|
||
{
|
||
m_transport?.SafeCancel();
|
||
m_transport?.SafeDispose();
|
||
m_transport = null;
|
||
WaitHandlePool?.CancelAll();
|
||
base.SafetyDispose(disposing);
|
||
}
|
||
}
|