A:增加PID单独信息获取;增加进程信息获取函数

This commit is contained in:
jimmy committed 2025-07-03 15:13:10 +08:00
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 重用问题:
+111 -14
View File
@@ -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 私有辅助方法