using System.Net.Http; using System.Text; using System.Text.Json; // 適用於 .NET Core 3.0+ / .NET 5/6/7/8 using System.Net; using System.Net.Sockets; using System.Diagnostics; using System.IO; using Microsoft.VisualBasic.Devices; namespace HeartbeatSender { public class heartbeatSender { private readonly HttpClient httpClient = new HttpClient(); private string token; private string token_heartbeatUrl; private string init_heartbeatUrl; public heartbeatSender() { LoadHeartbeatUrls("txt/HeartBeat.txt"); } /// /// 讀取URL /// /// 路徑 private void LoadHeartbeatUrls(string filePath) { if (!File.Exists(filePath)) { Console.WriteLine("找不到 HeartBeat.txt"); return; } string[] lines = File.ReadAllLines(filePath); foreach (string line in lines) { if (line.StartsWith("init:")) { init_heartbeatUrl = line.Substring("init:".Length).Trim(); } else if (line.StartsWith("token:")) { token_heartbeatUrl = line.Substring("token:".Length).Trim(); } } Console.WriteLine("init URL: " + init_heartbeatUrl); Console.WriteLine("token URL: " + token_heartbeatUrl); } public static string GetLocalIPv4() { foreach (var ip in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip)) { return ip.ToString(); } } return "127.0.0.1"; // fallback } public async Task LoginAndGetTokenAsync() { // init_heartbeat //var loginUrl = "http://zqd.superstar.dnsnet.cc/api/room/receiveRegister"; string hostName = System.Net.Dns.GetHostName(); var loginPayload = new { branch_name = "測試", room_name = "PC" + hostName.Substring(Math.Max(0, hostName.Length - 3)), room_ip = GetLocalIPv4(), email = "MachineKTV@gmail.com", password = "aa147258-" }; var json = JsonSerializer.Serialize(loginPayload); var content = new StringContent(json, Encoding.UTF8, "application/json"); try { var response = await httpClient.PostAsync(init_heartbeatUrl, content); response.EnsureSuccessStatusCode(); var responseJson = await response.Content.ReadAsStringAsync(); // Console.WriteLine("API 回傳內容:" + responseJson); using var doc = JsonDocument.Parse(responseJson); if (doc.RootElement.TryGetProperty("data", out JsonElement dataElement) && dataElement.ValueKind == JsonValueKind.Object) { if (dataElement.TryGetProperty("token", out JsonElement tokenElement)) { token = tokenElement.GetString(); } } // Console.WriteLine("登入成功,取得 token:" + token); return true; } catch (Exception ex) { Console.WriteLine($"登入失敗:{ex.Message}"); return false; } } public async Task SendHeartbeatAsync() { if (string.IsNullOrEmpty(token)) { Console.WriteLine("請先登入取得 token"); return; } //Console.WriteLine(GetLocalIPv4()); string hostName = System.Net.Dns.GetHostName(); var heartbeatData = new { branch_name = "測試", hostname = "PC" + hostName.Substring(Math.Max(0, hostName.Length - 3)), ip = GetLocalIPv4(), cpu = GetCpuUsage(), memory = GetTotalMemoryInMB(), disk = GetDiskTotalSizeInGB() }; var json = JsonSerializer.Serialize(heartbeatData); var content = new StringContent(json, Encoding.UTF8, "application/json"); // token_heartbeat // heartbeatUrl = "http://zqd.superstar.dnsnet.cc/api/room/heartbeat"; var request = new HttpRequestMessage(HttpMethod.Post, token_heartbeatUrl); request.Content = content; request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); // Console.WriteLine("送出的 JSON:"); // Console.WriteLine(json); var response = await httpClient.SendAsync(request); try { // Console.WriteLine($"心跳送出狀態:{response.StatusCode}"); response.EnsureSuccessStatusCode(); var responseJson = await response.Content.ReadAsStringAsync(); using var doc = JsonDocument.Parse(responseJson); // Console.WriteLine("API 回傳內容:" + responseJson); } catch (Exception ex) { var errorContent = await response.Content.ReadAsStringAsync(); Console.WriteLine($"送出心跳錯誤:{ex.Message}"); Console.WriteLine($"後端回應內容:{errorContent}"); } } private float GetCpuUsage() { using var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); cpuCounter.NextValue(); // 需要呼叫兩次 System.Threading.Thread.Sleep(100); return cpuCounter.NextValue(); // 回傳的是百分比,例如 25.3 } private float GetTotalMemoryInMB() { var computerInfo = new ComputerInfo(); return computerInfo.TotalPhysicalMemory / (1024f * 1024f); // 轉 MB } private float GetDiskTotalSizeInGB(string driveLetter = "C") { var drive = new DriveInfo(driveLetter); return drive.TotalSize / (1024f * 1024f * 1024f); // 轉 GB } } }