123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- using ProtocalGeneral;
- namespace FinsTcp;
- public class Fins_Tcp : IDisposable
- {
- private FinsTcpBase? _Service;
- private ITcpConnectNority? _tcpConnect;
- private string _IP = string.Empty;
- private int _port = 0;
- private Timer? _reconnectTimer;
- private Timer? _heartBeatTimer;
- private volatile ushort _heartBeatMissCount = 0;
- private ushort _maxHeartBeatMissCount = 5;
- private Func<bool>? _heartBeatCallBack;
- public bool Initialize(ITcpConnectNority? tcpConnect)
- {
- if (this._Service is not null)
- return false;
- this._Service = new FinsTcpBase();
- this._tcpConnect = tcpConnect;
- return true;
- }
- public bool Connect(string IP, int port, Func<bool> func, ushort heartBeatMissCount = 5, short heartBeatInterval = 1000, int sendTimeout = 1000, int receiveTimeout = 1000)
- {
- if (this._Service is null)
- return false;
- this._IP = IP;
- this._port = port;
- try
- {
- if (!this._Service.Link(IP, port, sendTimeout, receiveTimeout))
- return false;
- this._tcpConnect?.Connect(IP, port);
- this.StartHeartBeat(func, heartBeatMissCount, heartBeatInterval);
- }
- catch
- {
- return false;
- }
- return true;
- }
- private bool StartHeartBeat(Func<bool> func, ushort missCount = 5, short interval_ms = 1000)
- {
- if (this._heartBeatTimer is not null)
- return false;
- if (this._Service is null)
- return false;
- if (func is null)
- return false;
- this._maxHeartBeatMissCount = missCount;
- this._heartBeatCallBack = func;
- this._heartBeatTimer = new(HeatBeaterTimerCallBack, func, 0, interval_ms);
- return true;
- }
- private void HeatBeaterTimerCallBack(object? state)
- {
- if (this._heartBeatCallBack is null)
- return;
- if (this._heartBeatCallBack.Invoke())
- return;
- if (++_heartBeatMissCount <= this._maxHeartBeatMissCount)
- return;
- this._heartBeatTimer?.Dispose();
- this._tcpConnect?.DisConnect(this._IP, this._port);
- StartAutoReconnectTimer();
- }
- private void StartAutoReconnectTimer()
- {
- this._heartBeatTimer?.Dispose();
- this._heartBeatTimer = null;
- this._heartBeatMissCount = 0;
- this._reconnectTimer = new(ReconnectTimerCallBack, null, 0, 3000);
- }
- private void ReconnectTimerCallBack(object? state)
- {
- this._Service?.Close();
- this._Service = null;
- this._heartBeatTimer?.Dispose();
- this.Initialize(this._tcpConnect);
- if (!this.Connect(this._IP, this._port, this._heartBeatCallBack!, this._maxHeartBeatMissCount))
- return;
- this._reconnectTimer?.Dispose();
- }
- public bool GetData<T>(string address, out T? data)
- {
- data = default;
- if (this._Service is null)
- return false;
- try
- {
- switch (Type.GetTypeCode(typeof(T)))
- {
- case TypeCode.Boolean:
- if (!this._Service.GetBitState(address, out short state))
- return false;
- data = (T)(object)state;
- return true;
- case TypeCode.Int16:
- if (!this._Service.ReadWord(address, out short s))
- return false;
- data = (T)(object)s;
- return true;
- case TypeCode.Int32:
- if (!this._Service.ReadInt32(address, out int i))
- return false;
- data = (T)(object)i;
- return true;
- case TypeCode.Single:
- if (!this._Service.ReadReal(address, out float f))
- return false;
- data = (T)(object)f;
- return true;
- default:
- return false;
- }
- }
- catch
- {
- return false;
- }
- }
- public bool SetData<T>(string address, T data) where T : new()
- {
- if (this._Service is null)
- return false;
- try
- {
- return data switch
- {
- bool b => this._Service.SetBitState(address, b ? BitState.ON : BitState.OFF),
- short s => this._Service.WriteWord(address, s),
- int i => this._Service.WriteInt32(address, i),
- float f => this._Service.WriteReal(address, f),
- _ => false
- };
- }
- catch
- {
- return false;
- }
- }
- #region Dispose
- private bool disposedValue;
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- this._Service?.Close();
- this._Service = null;
- this._heartBeatTimer?.Dispose();
- this._reconnectTimer?.Dispose();
- this._tcpConnect?.DisConnect(this._IP, this._port);
- this._heartBeatMissCount = 0;
- }
- disposedValue = true;
- }
- }
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
- #endregion
- }
|