//------------------------------------------------------------------------------
// 此代码版权(除特别声明或在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);
}
}
}
}