using RTCommunicatorBase; using System.Collections.Concurrent; using System.Text; using System.Threading; using System.Threading.Tasks; using TLVProtocal; using UniversalNetFrame451; using UniversalNetFrame451.IO; namespace RTCommunicatorTLV; public class RTCommunicator_TLV : IRTMini8Sender, ITlvProvider { private IRTMini8Provider _provider; private ITlvCommunicatorClient _client; private readonly ConcurrentDictionary _DisconnectNotifyTimer = []; public bool Initialize(IRTMini8Provider provider) { if (provider is null) return false; if (this._provider is not null) return false; this._provider = provider; return true; } public bool StartService(string ip, int port) { if (_provider is null) return false; if (this._client is not null) return false; if (string.IsNullOrEmpty(ip) || port < 5000 || port > ushort.MaxValue) return false; ITlvCommunicatorClient client = TlvFactory.GetTlvClient(); if (!client.Initialize(this, false, 500)) return false; Task.Factory.StartNew(() => { while (!client.Open(ip, (ushort)port)) { Thread.Sleep(1000); } this._client = client; this._provider?.Connected(ip, port); }); return true; } public bool CloseService() { this._client?.Dispose(); this._client = null; this._provider = null; return true; } public bool SelectConfigFile(string name) { if (this._client is null) return false; if (string.IsNullOrEmpty(name)) return false; byte[] bytes = Encoding.UTF8.GetBytes(name); TlvData data = new(1, bytes); return this._client?.SendNotify(data) == true; } void ITlvProvider.Received(TlvData data) { if (data.RawData is null || data.RawData.Length == 0) return; Task.Factory.StartNew(() => { switch (data.Tag) { case Tags.CurrentTempConfigFile: string fileName = Encoding.UTF8.GetString(data.RawData); if (string.IsNullOrEmpty(fileName)) return; this._provider?.CurrentTempConfigFile(fileName); break; case Tags.ChannelAlarmNotify: if (!StructConverter.TryGetStruct(data.RawData, out ST_ALARM? alarm) || alarm is null) return; this._provider?.ChannelAlarmNotify(alarm.Value); break; case Tags.Mini8ConnectNotify: { byte index = data.RawData[0]; this._DisconnectNotifyTimer.TryRemove(index, out Timer timer); timer?.Dispose(); this._provider?.Mini8ConnectNotify(index); break; } case Tags.Mini8DisconnectNotify: { byte index = data.RawData[0]; if (!this._DisconnectNotifyTimer.ContainsKey(index)) this._DisconnectNotifyTimer[index] = new(DisconnectNotifyTimerCallBack, index, 0, 1000); break; } default: break; } }); } TlvData ITlvProvider.RequestReply(TlvData tlvData) { return tlvData; } void ITlvProvider.Connected(TcpConnection connection) { this._provider.Connected(connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port); } void ITlvProvider.Disconnected(TcpConnection connection) { this._provider.DisConnected(connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port); } private void DisconnectNotifyTimerCallBack(object state) { if (state is not byte index) return; this._provider?.Mini8DisconnectNotify(index); } }