//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Threading; using TouchSocket.Core; using TouchSocket.Sockets; namespace TouchSocket.Rpc.TouchRpc { /// /// TouchRpcHeartbeatPlugin /// [SingletonPlugin] public class TouchRpcHeartbeatPlugin : TouchRpcPluginBase where TClient : IDependencyObject, ITcpClientBase, IDependencyTouchRpc { private TClient m_client; private Thread m_thread; /// /// 连接失败次数。当成功连接时,会重置为0。 /// public int FailedCount { get; private set; } /// /// 心跳间隔。默认3秒。 /// public TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(3); /// /// 最大失败次数,默认3。 /// public int MaxFailCount { get; set; } = 3; /// /// 心跳间隔。默认3秒。 /// /// /// public TouchRpcHeartbeatPlugin SetInterval(TimeSpan value) { if (value == TimeSpan.Zero || value == TimeSpan.MaxValue || value == TimeSpan.MinValue) { throw new InvalidTimeZoneException("设置的时间必须为有效值。"); } Interval = value; return this; } /// /// 最大失败次数,默认3。 /// /// /// public TouchRpcHeartbeatPlugin SetMaxFailCount(int value) { MaxFailCount = value; return this; } /// /// /// /// /// protected override void OnHandshaked(TClient client, VerifyOptionEventArgs e) { m_client = client; if (m_thread == null) { m_thread = new Thread(ThreadHeartbeat) { IsBackground = true, Name = $"{client}HeartbeatThread" }; m_thread.Start(); } base.OnHandshaked(client, e); } private void ThreadHeartbeat(object obj) { while (true) { if (DisposedValue) { return; } if (m_client.IsHandshaked && (DateTime.Now.TimeOfDay - m_client.GetLastActiveTime().TimeOfDay > Interval)) { if (m_client.Ping()) { FailedCount = 0; } else { FailedCount++; if (FailedCount > MaxFailCount) { m_client.SafeClose("自动心跳失败次数达到最大,已断开连接。"); } } } Thread.Sleep(Interval); } } } }