|
@@ -1,4 +1,5 @@
|
|
|
-using System.Net.NetworkInformation;
|
|
|
+using System.Collections.Concurrent;
|
|
|
+using System.Net.NetworkInformation;
|
|
|
|
|
|
namespace WCS.Core;
|
|
|
|
|
@@ -6,32 +7,126 @@ public class PLC : EntityEx<PLCInfo>
|
|
|
{
|
|
|
public PLC(PLCInfo ent, World world) : base(ent)
|
|
|
{
|
|
|
- if (Configs.PLCAccessorCreater != null)
|
|
|
- Accessor = Configs.PLCAccessorCreater.Create(ent);
|
|
|
- else
|
|
|
- throw new Exception("Configs.PLCAccessorCreater未赋值");
|
|
|
+ if (Configs.PLCAccessorCreater != null) Accessor = Configs.PLCAccessorCreater.Create(ent);
|
|
|
+ else throw new Exception("Configs.PLCAccessorCreater未赋值");
|
|
|
|
|
|
- Task.Run(() =>
|
|
|
+ IPDetection.AddIP(Entity.IP);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool Ping { get => IPDetection.GetIpStatus(Entity.IP); }
|
|
|
+
|
|
|
+ public IPLCAccessor Accessor { get; private set; }
|
|
|
+}
|
|
|
+
|
|
|
+public class IPDetection
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 需要检测的IP组,使用线程安全的字典
|
|
|
+ /// </summary>
|
|
|
+ private static ConcurrentDictionary<string, bool> _ipDetection = new ConcurrentDictionary<string, bool>();
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 是否启动检测器
|
|
|
+ /// </summary>
|
|
|
+ private static bool isStart = false;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 取消标记,用于停止检测任务
|
|
|
+ /// </summary>
|
|
|
+ private static CancellationTokenSource cancellationTokenSource;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 添加IP进行检测
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="ip"></param>
|
|
|
+ public static void AddIP(string ip)
|
|
|
+ {
|
|
|
+ if (!_ipDetection.ContainsKey(ip))
|
|
|
+ {
|
|
|
+ _ipDetection[ip] = false; // 默认为不在线
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isStart)
|
|
|
{
|
|
|
- while (true)
|
|
|
+ isStart = true;
|
|
|
+ Start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取指定IP的状态
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="ip"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool GetIpStatus(string ip)
|
|
|
+ {
|
|
|
+ return _ipDetection.ContainsKey(ip) && _ipDetection[ip];
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 启动IP检测任务
|
|
|
+ /// </summary>
|
|
|
+ private static void Start()
|
|
|
+ {
|
|
|
+ cancellationTokenSource = new CancellationTokenSource();
|
|
|
+ Task.Run(async () =>
|
|
|
+ {
|
|
|
+ while (!cancellationTokenSource.Token.IsCancellationRequested)
|
|
|
{
|
|
|
- Ping = ping();
|
|
|
- Task.Delay(1000).Wait();
|
|
|
+ await CheckIpsAsync();
|
|
|
+ await Task.Delay(1000); // 等待 1 秒
|
|
|
}
|
|
|
- // ReSharper disable once FunctionNeverReturns
|
|
|
- });
|
|
|
+ }, cancellationTokenSource.Token);
|
|
|
}
|
|
|
|
|
|
- public bool Ping { get; private set; }
|
|
|
+ /// <summary>
|
|
|
+ /// 停止IP检测任务
|
|
|
+ /// </summary>
|
|
|
+ public static void Stop()
|
|
|
+ {
|
|
|
+ cancellationTokenSource?.Cancel();
|
|
|
+ isStart = false;
|
|
|
+ }
|
|
|
|
|
|
- public IPLCAccessor Accessor { get; private set; }
|
|
|
+ /// <summary>
|
|
|
+ /// 检测所有IP的状态
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ private static async Task CheckIpsAsync()
|
|
|
+ {
|
|
|
+ var tasks = new List<Task>();
|
|
|
|
|
|
- private bool ping(int timeout = 300)
|
|
|
+ foreach (var ip in _ipDetection.Keys.ToList()) // 使用 ToList 防止遍历时修改字典
|
|
|
+ {
|
|
|
+ tasks.Add(Task.Run(async () =>
|
|
|
+ {
|
|
|
+ bool isOnline = await PingAsync(ip);
|
|
|
+ _ipDetection[ip] = isOnline;
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ await Task.WhenAll(tasks);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// pingIp
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="ip"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private static async Task<bool> PingAsync(string ip)
|
|
|
{
|
|
|
- var p = new Ping();
|
|
|
- if (Entity.IP == "1") return false;
|
|
|
- var res = p.Send(Entity.IP, timeout);
|
|
|
- return res.Status == IPStatus.Success;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (ip == "1") return false;
|
|
|
+ Ping ping = new Ping();
|
|
|
+ PingReply reply = await ping.SendPingAsync(ip, 300); // 设置超时时间为300毫秒
|
|
|
+ return reply.Status == IPStatus.Success;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ // 如果出现异常,认为该IP不可用
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|