A:增加PID单独信息获取;增加进程信息获取函数
This commit is contained in:
1 parent
d1ecd6b6e2
commit
095783ea61
4 files changed
+242
-17
No files matched your search
@@ -27,14 +27,17 @@ public sealed class ProcessCache
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 缓存字典【给定初始量 1000 ,后期可根据需求调整,避免频繁扩容】
|
/// 缓存字典【给定初始量 1000 ,后期可根据需求调整,避免频繁扩容】
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<string, ProgramInfo> _cache = new(1000);
|
private readonly Dictionary<string, CacheItem> _cache = new(1000);
|
||||||
|
|
||||||
// 设置缓存
|
// 设置缓存
|
||||||
public void Set(string key, ProgramInfo value)
|
public void Set(string key, ProgramInfo value)
|
||||||
{
|
{
|
||||||
lock (_cache)
|
lock (_cache)
|
||||||
{
|
{
|
||||||
_cache[key] = value;
|
_cache[key] = new CacheItem
|
||||||
|
{
|
||||||
|
Info = value
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +46,16 @@ public sealed class ProcessCache
|
|||||||
{
|
{
|
||||||
lock (_cache)
|
lock (_cache)
|
||||||
{
|
{
|
||||||
return _cache.GetValueOrDefault(key);
|
if (_cache.TryGetValue(key, out var item))
|
||||||
|
{
|
||||||
|
if ((DateTime.Now - item.TimeStamp).TotalMinutes < 2)
|
||||||
|
return item.Info;
|
||||||
|
|
||||||
|
// 超时,移除
|
||||||
|
_cache.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +68,12 @@ public sealed class ProcessCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CacheItem
|
||||||
|
{
|
||||||
|
public required ProgramInfo Info { get; init; }
|
||||||
|
public DateTime TimeStamp { get; init; } = DateTime.Now;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
PID 重用问题:
|
PID 重用问题:
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using Common.Logger;
|
|||||||
using Common.Net.HttpConn;
|
using Common.Net.HttpConn;
|
||||||
using Common.Net.Models;
|
using Common.Net.Models;
|
||||||
using Common.Net.WebSocketConn;
|
using Common.Net.WebSocketConn;
|
||||||
|
using Common.Utils;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Utils.ETW.Etw;
|
using Utils.ETW.Etw;
|
||||||
@@ -135,11 +136,16 @@ public partial class App : System.Windows.Application
|
|||||||
// 订阅 websocket 关闭服务
|
// 订阅 websocket 关闭服务
|
||||||
WebSocketManager.Instance.SubscribeConnectionClosed((args =>
|
WebSocketManager.Instance.SubscribeConnectionClosed((args =>
|
||||||
{
|
{
|
||||||
if (args.Uuid != null) DispatchEngine.Instance.DeleteApplicationInfo(args.Uuid);
|
if (args.Uuid != null)
|
||||||
|
{
|
||||||
|
DispatchEngine.Instance.DeleteApplicationInfo(args.Uuid);
|
||||||
|
DispatchEngine.Instance.DeleteProcessInfo(args.Uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
// 开启 WebSocket 定时发送服务
|
// 开启 WebSocket 定时发送服务
|
||||||
DispatchEngine.Instance.ApplicationInfoDistribute();
|
DispatchEngine.Instance.ApplicationInfoDistribute();
|
||||||
|
DispatchEngine.Instance.ProcessInfoDistribute();
|
||||||
|
|
||||||
// 启动 http 服务
|
// 启动 http 服务
|
||||||
Task.Run(() => { _ = StartHttpServer(); });
|
Task.Run(() => { _ = StartHttpServer(); });
|
||||||
@@ -174,8 +180,9 @@ public partial class App : System.Windows.Application
|
|||||||
server.Get("/api",
|
server.Get("/api",
|
||||||
async (context) => { await context.Response.WriteJsonAsync(new { message = "Hi!" }); });
|
async (context) => { await context.Response.WriteJsonAsync(new { message = "Hi!" }); });
|
||||||
|
|
||||||
// 订阅某信息
|
#region 软件信息订阅
|
||||||
server.Post("/api/subscribe", async (context) =>
|
|
||||||
|
server.Post("/api/subscribe-application", async (context) =>
|
||||||
{
|
{
|
||||||
// 正确的做法:只处理请求体数据
|
// 正确的做法:只处理请求体数据
|
||||||
if (string.IsNullOrEmpty(context.RequestBody))
|
if (string.IsNullOrEmpty(context.RequestBody))
|
||||||
@@ -199,18 +206,27 @@ public partial class App : System.Windows.Application
|
|||||||
string? uuid = context.Request.Headers["uuid"];
|
string? uuid = context.Request.Headers["uuid"];
|
||||||
Log.Warning($"接收到的数据: {requestData}, 用户 Id: {uuid}");
|
Log.Warning($"接收到的数据: {requestData}, 用户 Id: {uuid}");
|
||||||
|
|
||||||
var subscriptionInfo = JsonSerializer.Deserialize<SubscriptionInfo>(requestData);
|
if (string.IsNullOrWhiteSpace(uuid))
|
||||||
if (subscriptionInfo != null && !string.IsNullOrWhiteSpace(uuid))
|
|
||||||
{
|
{
|
||||||
if (AppConfig.ApplicationInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
|
context.Response.StatusCode = 400;
|
||||||
|
await context.Response.WriteJsonAsync(new ResponseModel<object>
|
||||||
{
|
{
|
||||||
DispatchEngine.Instance.AddApplicationInfo(uuid, new DispatchModel
|
Success = false,
|
||||||
{
|
Message = $"用户 ID 丢失!",
|
||||||
Interval = subscriptionInfo.Interval
|
});
|
||||||
});
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var subscriptionInfo = JsonHelper.FromJson<SubscriptionInfo>(requestData);
|
||||||
|
if (subscriptionInfo != null)
|
||||||
|
{
|
||||||
|
// 软件信息订阅
|
||||||
|
DispatchEngine.Instance.AddApplicationInfo(uuid, new DispatchModel
|
||||||
|
{
|
||||||
|
Interval = subscriptionInfo.Interval
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
Log.Warning($"名称: {subscriptionInfo.SubscriptionType}");
|
|
||||||
Log.Warning($"时间: {subscriptionInfo.Interval}");
|
Log.Warning($"时间: {subscriptionInfo.Interval}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +251,81 @@ public partial class App : System.Windows.Application
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 取消订阅
|
#endregion
|
||||||
|
|
||||||
|
#region 线程信息订阅
|
||||||
|
|
||||||
|
server.Post("/api/subscribe-process", async (context) =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(context.RequestBody))
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 400;
|
||||||
|
await context.Response.WriteJsonAsync(new ResponseModel<object>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Message = "请求体不能为空",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析请求数据
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string requestData = context.RequestBody;
|
||||||
|
|
||||||
|
// 打印原始数据用于调试
|
||||||
|
string? uuid = context.Request.Headers["uuid"];
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(uuid))
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 400;
|
||||||
|
await context.Response.WriteJsonAsync(new ResponseModel<object>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Message = $"用户 ID 丢失!",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var subscriptionInfo = JsonHelper.FromJson<SubscriptionProcessInfo>(requestData);
|
||||||
|
if (subscriptionInfo != null)
|
||||||
|
{
|
||||||
|
DispatchEngine.Instance.DeleteProcessInfo(uuid);
|
||||||
|
DispatchEngine.Instance.AddProcessInfo(uuid, new ProcessDispatchModel
|
||||||
|
{
|
||||||
|
Interval = subscriptionInfo.Interval,
|
||||||
|
ProcessIds = subscriptionInfo.ProcessIds
|
||||||
|
});
|
||||||
|
Log.Warning($"时间: {subscriptionInfo.Interval}");
|
||||||
|
Log.Warning($"监视的 ID : {subscriptionInfo.ProcessIds}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JsonException ex)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 400;
|
||||||
|
await context.Response.WriteJsonAsync(new ResponseModel<object>
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Message = $"请求数据格式错误: {ex.Message}",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回响应 - 只序列化纯数据对象
|
||||||
|
context.Response.StatusCode = 200;
|
||||||
|
await context.Response.WriteJsonAsync(new ResponseModel<string>
|
||||||
|
{
|
||||||
|
Success = true,
|
||||||
|
Data = "成功",
|
||||||
|
Message = "订阅成功",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region 取消订阅
|
||||||
|
|
||||||
server.Post("/api/unsubscribe", async (context) =>
|
server.Post("/api/unsubscribe", async (context) =>
|
||||||
{
|
{
|
||||||
// 正确的做法:只处理请求体数据
|
// 正确的做法:只处理请求体数据
|
||||||
@@ -260,13 +350,19 @@ public partial class App : System.Windows.Application
|
|||||||
string? uuid = context.Request.Headers["uuid"];
|
string? uuid = context.Request.Headers["uuid"];
|
||||||
Log.Warning($"接收到的数据: {requestData}, 用户 Id: {uuid}");
|
Log.Warning($"接收到的数据: {requestData}, 用户 Id: {uuid}");
|
||||||
|
|
||||||
var subscriptionInfo = JsonSerializer.Deserialize<SubscriptionInfo>(requestData);
|
var subscriptionInfo = JsonHelper.FromJson<SubscriptionInfo>(requestData);
|
||||||
if (subscriptionInfo != null && !string.IsNullOrWhiteSpace(uuid))
|
if (subscriptionInfo != null && !string.IsNullOrWhiteSpace(uuid))
|
||||||
{
|
{
|
||||||
|
// 软件信息订阅
|
||||||
if (AppConfig.ApplicationInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
|
if (AppConfig.ApplicationInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
|
||||||
{
|
{
|
||||||
DispatchEngine.Instance.DeleteApplicationInfo(uuid);
|
DispatchEngine.Instance.DeleteApplicationInfo(uuid);
|
||||||
}
|
}
|
||||||
|
// 进程信息订阅
|
||||||
|
else if (AppConfig.ProcessInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
|
||||||
|
{
|
||||||
|
DispatchEngine.Instance.DeleteProcessInfo(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
Log.Warning($"取消订阅的 名称: {subscriptionInfo.SubscriptionType}");
|
Log.Warning($"取消订阅的 名称: {subscriptionInfo.SubscriptionType}");
|
||||||
}
|
}
|
||||||
@@ -292,6 +388,7 @@ public partial class App : System.Windows.Application
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
// 启动服务器
|
// 启动服务器
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -27,6 +27,87 @@ public class ProcessNetworkInfo
|
|||||||
public List<string> ActiveConnections { get; set; } = new List<string>();
|
public List<string> ActiveConnections { get; set; } = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 进程信息
|
||||||
|
/// </summary>
|
||||||
|
public class ProcessType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 进程名称
|
||||||
|
/// </summary>
|
||||||
|
public string ProcessName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 进程ID
|
||||||
|
/// </summary>
|
||||||
|
public int ProcessId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime StartTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否退出
|
||||||
|
/// </summary>
|
||||||
|
public bool HasExited { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 退出时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? ExitTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 退出代码
|
||||||
|
/// </summary>
|
||||||
|
public int? ExitCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 占用内存
|
||||||
|
/// </summary>
|
||||||
|
public long UseMemory { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 线程数
|
||||||
|
/// </summary>
|
||||||
|
public int ThreadCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主模块路径
|
||||||
|
/// </summary>
|
||||||
|
public string? MainModulePath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动文件名
|
||||||
|
/// </summary>
|
||||||
|
public string? MainModuleName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上行总量
|
||||||
|
/// </summary>
|
||||||
|
public long TotalUploaded { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下行总量
|
||||||
|
/// </summary>
|
||||||
|
public long TotalDownloaded { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上行速度
|
||||||
|
/// </summary>
|
||||||
|
public double UploadSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下行速度
|
||||||
|
/// </summary>
|
||||||
|
public double DownloadSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所有连接
|
||||||
|
/// </summary>
|
||||||
|
public List<ConnectionInfo> Connections { get; set; } = new List<ConnectionInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 连接详细信息
|
/// 连接详细信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -35,14 +116,17 @@ public class ConnectionInfo
|
|||||||
public string ConnectionKey { get; set; }
|
public string ConnectionKey { get; set; }
|
||||||
public int ProcessId { get; set; }
|
public int ProcessId { get; set; }
|
||||||
public ProtocolType Protocol { get; set; }
|
public ProtocolType Protocol { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本地 终结点
|
/// 本地 终结点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IPEndPoint LocalEndpoint { get; set; }
|
public IPEndPoint LocalEndpoint { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 目标 终结点
|
/// 目标 终结点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IPEndPoint RemoteEndpoint { get; set; }
|
public IPEndPoint RemoteEndpoint { get; set; }
|
||||||
|
|
||||||
public ConnectionState State { get; set; }
|
public ConnectionState State { get; set; }
|
||||||
public TrafficDirection Direction { get; set; }
|
public TrafficDirection Direction { get; set; }
|
||||||
public DateTime StartTime { get; set; }
|
public DateTime StartTime { get; set; }
|
||||||
@@ -138,10 +222,12 @@ public class ConnectionSnapshot
|
|||||||
public int RemotePort { get; set; }
|
public int RemotePort { get; set; }
|
||||||
public string RemoteDomain { get; set; }
|
public string RemoteDomain { get; set; }
|
||||||
public string State { get; set; }
|
public string State { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 方向
|
/// 方向
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Direction { get; set; }
|
public string Direction { get; set; }
|
||||||
|
|
||||||
public DateTime StartTime { get; set; }
|
public DateTime StartTime { get; set; }
|
||||||
public TimeSpan Duration { get; set; }
|
public TimeSpan Duration { get; set; }
|
||||||
public long BytesSent { get; set; }
|
public long BytesSent { get; set; }
|
||||||
|
|||||||
@@ -390,6 +390,30 @@ public sealed class GlobalNetworkMonitor
|
|||||||
return _applications.Values.ToList().Select(applicationInfo => applicationInfo.ProgramInfo).ToList();
|
return _applications.Values.ToList().Select(applicationInfo => applicationInfo.ProgramInfo).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定的 pid 连接
|
||||||
|
/// </summary>
|
||||||
|
public List<ConnectionInfo> GetAllConnection(List<int> processIds)
|
||||||
|
{
|
||||||
|
var connectionInfos = _connections.Values.ToList();
|
||||||
|
var ansList = new List<ConnectionInfo>();
|
||||||
|
foreach (var t in processIds)
|
||||||
|
{
|
||||||
|
var infos = GetConnection(t);
|
||||||
|
|
||||||
|
ansList.AddRange(infos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ansList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ConnectionInfo> GetConnection(int processIds)
|
||||||
|
{
|
||||||
|
var connectionInfos = _connections.Values.ToList();
|
||||||
|
var infos = connectionInfos.FindAll(info => info.ProcessId == processIds);
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 私有辅助方法
|
#region 私有辅助方法
|
||||||
|
|||||||
Reference in new issue
Block a user