心跳封包
This commit is contained in:
parent
4d02d56152
commit
c623bbe26d
@ -1,39 +1,132 @@
|
|||||||
|
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;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
|
||||||
using System.Timers;
|
namespace HeartbeatSender
|
||||||
namespace HeartbeatSender{
|
{
|
||||||
|
|
||||||
|
public class HeartbeatData
|
||||||
|
{
|
||||||
|
public string branch_name { get; set; }
|
||||||
|
public string room_name { get; set; }
|
||||||
|
public string room_ip { get; set; }
|
||||||
|
public string email { get; set; }
|
||||||
|
public string password { get; set; }
|
||||||
|
}
|
||||||
public class heartbeatSender
|
public class heartbeatSender
|
||||||
{
|
{
|
||||||
private readonly UdpClient udpClient;
|
private readonly HttpClient httpClient = new HttpClient();
|
||||||
private readonly IPEndPoint remoteEndPoint;
|
private string token;
|
||||||
private readonly System.Timers.Timer heartbeatTimer;
|
private string heartbeatUrl;
|
||||||
public IPEndPoint RemoteEndPoint => remoteEndPoint;
|
|
||||||
public heartbeatSender(string targetIp, int targetPort, int intervalMilliseconds = 3000)
|
public heartbeatSender(string heartbeatUrl)
|
||||||
{
|
{
|
||||||
udpClient = new UdpClient();
|
this.heartbeatUrl = heartbeatUrl;
|
||||||
// 設置 IP 和 PORT
|
|
||||||
remoteEndPoint = new IPEndPoint(IPAddress.Parse(targetIp), targetPort);
|
|
||||||
// 每3秒發送一次
|
|
||||||
heartbeatTimer = new System.Timers.Timer(intervalMilliseconds);
|
|
||||||
heartbeatTimer.Elapsed += SendHeartbeat;
|
|
||||||
heartbeatTimer.AutoReset = true;
|
|
||||||
}
|
}
|
||||||
private void SendHeartbeat(object sender, ElapsedEventArgs e)
|
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<bool> LoginAndGetTokenAsync()
|
||||||
|
{
|
||||||
|
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
|
try
|
||||||
{
|
{
|
||||||
string heartbeatMessage = "HEARTBEAT";
|
var response = await httpClient.PostAsync(loginUrl, content);
|
||||||
byte[] data = Encoding.UTF8.GetBytes(heartbeatMessage);
|
response.EnsureSuccessStatusCode();
|
||||||
udpClient.Send(data, data.Length, remoteEndPoint);
|
|
||||||
Console.WriteLine($"Heartbeat sent to {remoteEndPoint.Address}:{remoteEndPoint.Port}");
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Error sending heartbeat: {ex.Message}");
|
Console.WriteLine($"登入失敗:{ex.Message}");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Start() => heartbeatTimer.Start();
|
|
||||||
public void Stop() => heartbeatTimer.Stop();
|
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(),
|
||||||
|
};
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(heartbeatData);
|
||||||
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||||
|
heartbeatUrl = "http://zqd.superstar.dnsnet.cc/api/room/heartbeat";
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Post, 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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
@ -6,14 +6,50 @@ using System.Diagnostics;
|
|||||||
namespace DualScreenDemo{
|
namespace DualScreenDemo{
|
||||||
public partial class PrimaryForm
|
public partial class PrimaryForm
|
||||||
{
|
{
|
||||||
|
private static string connectionStringfortest = "";
|
||||||
|
public static void LoadConnectionStringFromFile(string filePath)
|
||||||
|
{
|
||||||
|
filePath = Path.Combine(Application.StartupPath, "txt", filePath);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
string fileContent = File.ReadAllText(filePath).Trim();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(fileContent))
|
||||||
|
{
|
||||||
|
connectionStringfortest = fileContent;
|
||||||
|
Console.WriteLine("連線字串載入成功。");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("檔案內容為空。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("找不到指定的檔案:" + filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("讀取檔案時發生錯誤:" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetConnectionString()
|
||||||
|
{
|
||||||
|
return connectionStringfortest;
|
||||||
|
}
|
||||||
|
|
||||||
public bool isLoggedIn = false;
|
public bool isLoggedIn = false;
|
||||||
public string userPhone = string.Empty;
|
public string userPhone = string.Empty;
|
||||||
public List<SongData> SearchSongs_Mysql(string query)
|
public List<SongData> SearchSongs_Mysql(string query)
|
||||||
{
|
{
|
||||||
List<SongData> searchResults = new List<SongData>();
|
List<SongData> searchResults = new List<SongData>();
|
||||||
Console.WriteLine(query);
|
Console.WriteLine(query);
|
||||||
string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
//string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
||||||
|
string connectionString = GetConnectionString();
|
||||||
using (var connection = new MySqlConnection(connectionString))
|
using (var connection = new MySqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
Stopwatch stopwatch = new Stopwatch();
|
Stopwatch stopwatch = new Stopwatch();
|
||||||
@ -65,8 +101,8 @@ namespace DualScreenDemo{
|
|||||||
public static List<Artist> SearchSingers_Mysql(string query){
|
public static List<Artist> SearchSingers_Mysql(string query){
|
||||||
List<Artist> searchResults = new List<Artist>();
|
List<Artist> searchResults = new List<Artist>();
|
||||||
Console.WriteLine(query);
|
Console.WriteLine(query);
|
||||||
string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
//string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
||||||
|
string connectionString = GetConnectionString();
|
||||||
using (var connection = new MySqlConnection(connectionString))
|
using (var connection = new MySqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
Stopwatch stopwatch = new Stopwatch();
|
Stopwatch stopwatch = new Stopwatch();
|
||||||
@ -100,8 +136,8 @@ namespace DualScreenDemo{
|
|||||||
|
|
||||||
string query = $"INSERT INTO FavoriteSongs (userPhone,songNumber) VALUES ('{userPhone}','{songNumber}');";
|
string query = $"INSERT INTO FavoriteSongs (userPhone,songNumber) VALUES ('{userPhone}','{songNumber}');";
|
||||||
Console.WriteLine(query);
|
Console.WriteLine(query);
|
||||||
string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
//string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
||||||
|
string connectionString = GetConnectionString();
|
||||||
using (var connection = new MySqlConnection(connectionString))
|
using (var connection = new MySqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -128,8 +164,8 @@ namespace DualScreenDemo{
|
|||||||
string songlist = phonenumber + "的歌單";
|
string songlist = phonenumber + "的歌單";
|
||||||
string query = $"INSERT INTO FavoriteSongs (userPhone,songNumber) VALUES ('{phonenumber}','{songlist}');";
|
string query = $"INSERT INTO FavoriteSongs (userPhone,songNumber) VALUES ('{phonenumber}','{songlist}');";
|
||||||
Console.WriteLine(query);
|
Console.WriteLine(query);
|
||||||
string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
//string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
||||||
|
string connectionString = GetConnectionString();
|
||||||
using (var connection = new MySqlConnection(connectionString))
|
using (var connection = new MySqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -163,7 +199,8 @@ namespace DualScreenDemo{
|
|||||||
|
|
||||||
}
|
}
|
||||||
public bool checkPhoneNumberExist(string phonenumber){
|
public bool checkPhoneNumberExist(string phonenumber){
|
||||||
string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
//string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
||||||
|
string connectionString = GetConnectionString();
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
using (var connection = new MySqlConnection(connectionString))
|
using (var connection = new MySqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
@ -212,8 +249,8 @@ namespace DualScreenDemo{
|
|||||||
public void AddSongCount(string id){
|
public void AddSongCount(string id){
|
||||||
string query = $"UPDATE songs SET song_counts = song_counts+1 WHERE id = '{id}';";
|
string query = $"UPDATE songs SET song_counts = song_counts+1 WHERE id = '{id}';";
|
||||||
Console.WriteLine(query);
|
Console.WriteLine(query);
|
||||||
string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
//string connectionString = "Server=192.168.11.4;Port=3306;Database=Karaoke-Kingpin;User=Karaoke-Kingpin;Password=ESM7yTPMnavFmbBH;";
|
||||||
|
string connectionString = GetConnectionString();
|
||||||
using (var connection = new MySqlConnection(connectionString))
|
using (var connection = new MySqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -184,31 +184,31 @@ namespace DualScreenDemo
|
|||||||
public PrimaryForm()
|
public PrimaryForm()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
|
||||||
// 添加 DPI 感知支持
|
// 添加 DPI 感知支持
|
||||||
if (Environment.OSVersion.Version.Major >= 6)
|
if (Environment.OSVersion.Version.Major >= 6)
|
||||||
{
|
{
|
||||||
SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.DoubleBuffered = true;
|
this.DoubleBuffered = true;
|
||||||
|
|
||||||
InitializeProgressBar();
|
InitializeProgressBar();
|
||||||
|
|
||||||
// 初始化自动刷新Timer
|
// 初始化自动刷新Timer
|
||||||
autoRefreshTimer = new Timer();
|
autoRefreshTimer = new Timer();
|
||||||
autoRefreshTimer.Interval = 1000; // 1秒
|
autoRefreshTimer.Interval = 1000; // 1秒
|
||||||
autoRefreshTimer.Tick += AutoRefreshTimer_Tick;
|
autoRefreshTimer.Tick += AutoRefreshTimer_Tick;
|
||||||
|
|
||||||
// 設置窗體屬性
|
// 設置窗體屬性
|
||||||
this.WindowState = FormWindowState.Maximized;
|
this.WindowState = FormWindowState.Maximized;
|
||||||
this.FormBorderStyle = FormBorderStyle.None;
|
this.FormBorderStyle = FormBorderStyle.None;
|
||||||
|
|
||||||
lightControlTimer = new Timer();
|
lightControlTimer = new Timer();
|
||||||
lightControlTimer.Interval = 5;
|
lightControlTimer.Interval = 5;
|
||||||
lightControlTimer.Tick += LightControlTimer_Tick;
|
lightControlTimer.Tick += LightControlTimer_Tick;
|
||||||
volumeUpTimer = new Timer();
|
volumeUpTimer = new Timer();
|
||||||
volumeUpTimer.Interval = 100;
|
volumeUpTimer.Interval = 100;
|
||||||
volumeUpTimer.Tick += VolumeUpTimer_Tick;
|
volumeUpTimer.Tick += VolumeUpTimer_Tick;
|
||||||
volumeDownTimer = new Timer();
|
volumeDownTimer = new Timer();
|
||||||
volumeDownTimer.Interval = 100;
|
volumeDownTimer.Interval = 100;
|
||||||
@ -216,12 +216,12 @@ namespace DualScreenDemo
|
|||||||
micControlTimer = new Timer();
|
micControlTimer = new Timer();
|
||||||
micControlTimer.Interval = 100;
|
micControlTimer.Interval = 100;
|
||||||
micControlTimer.Tick += MicControlTimer_Tick;
|
micControlTimer.Tick += MicControlTimer_Tick;
|
||||||
|
|
||||||
InitializeRecording();
|
InitializeRecording();
|
||||||
InitializeMediaPlayer();
|
InitializeMediaPlayer();
|
||||||
LoadSongData();
|
LoadSongData();
|
||||||
LoadImages();
|
LoadImages();
|
||||||
InitializeFormAndControls();
|
InitializeFormAndControls();
|
||||||
InitializeMultiPagePanel();
|
InitializeMultiPagePanel();
|
||||||
OverlayQRCodeOnImage(HttpServer.randomFolderPath);
|
OverlayQRCodeOnImage(HttpServer.randomFolderPath);
|
||||||
|
|
||||||
@ -229,16 +229,17 @@ namespace DualScreenDemo
|
|||||||
InitializeHandWritingForSongs();
|
InitializeHandWritingForSongs();
|
||||||
|
|
||||||
InitializeSendOffPanel();
|
InitializeSendOffPanel();
|
||||||
|
|
||||||
InitializePromotionsAndMenuPanel();
|
InitializePromotionsAndMenuPanel();
|
||||||
SaveInitialControlStates(this);
|
SaveInitialControlStates(this);
|
||||||
// 包廂 + port 名稱
|
// 包廂 + port 名稱
|
||||||
this.Paint += PrimaryForm_Paint;
|
this.Paint += PrimaryForm_Paint;
|
||||||
this.Paint += User_Paint;
|
this.Paint += User_Paint;
|
||||||
// 註冊多頁面面板的頁碼改變事件處理
|
// 註冊多頁面面板的頁碼改變事件處理
|
||||||
multiPagePanel.PageIndexChanged += HandlePageChanged;
|
multiPagePanel.PageIndexChanged += HandlePageChanged;
|
||||||
// 添加 Load 事件處理
|
// 添加 Load 事件處理
|
||||||
this.Load += PrimaryForm_Load;
|
this.Load += PrimaryForm_Load;
|
||||||
|
LoadConnectionStringFromFile("test.env");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
156
Program.cs
156
Program.cs
@ -2,6 +2,7 @@ using System.IO;
|
|||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using DBObj;
|
using DBObj;
|
||||||
|
using HeartbeatSender;
|
||||||
|
|
||||||
namespace DualScreenDemo
|
namespace DualScreenDemo
|
||||||
{
|
{
|
||||||
@ -14,76 +15,101 @@ namespace DualScreenDemo
|
|||||||
private static PrimaryForm primaryForm; // 儲存實例的參考
|
private static PrimaryForm primaryForm; // 儲存實例的參考
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
static void Main()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// COM 初始化
|
|
||||||
int hr = ComInterop.CoInitializeEx(IntPtr.Zero, ComInterop.COINIT_APARTMENTTHREADED);
|
|
||||||
if (hr < 0)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine("Failed to initialize COM library.");
|
var sender = new HeartbeatSender.heartbeatSender("http://zqd.superstar.dnsnet.cc/api/room/receiveRegister");
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 初始化管理器
|
|
||||||
|
|
||||||
songListManager = new SongListManager(); // 使用单例
|
// 同步呼叫非同步登入取得 token
|
||||||
//artistManager = new ArtistManager();
|
bool loginSuccess = sender.LoginAndGetTokenAsync().GetAwaiter().GetResult();
|
||||||
|
|
||||||
var commandHandler = new CommandHandler(songListManager);
|
if (loginSuccess)
|
||||||
serialPortManager = new SerialPortManager(commandHandler);
|
|
||||||
serialPortManager.InitializeSerialPort();
|
|
||||||
|
|
||||||
// 輸出屏幕信息
|
|
||||||
Console.WriteLine($"Virtual Screen: {SystemInformation.VirtualScreen}");
|
|
||||||
foreach (var screen in Screen.AllScreens)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Screen: {screen.DeviceName} Resolution: {screen.Bounds.Width}x{screen.Bounds.Height}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 啟動服務器
|
|
||||||
Task.Run(() => HttpServerManager.StartServer());
|
|
||||||
Task.Run(() => TCPServerManager.StartServer());
|
|
||||||
|
|
||||||
// 註冊事件
|
|
||||||
Application.ApplicationExit += (sender, e) => SerialPortManager.CloseSerialPortSafely();
|
|
||||||
SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged;
|
|
||||||
|
|
||||||
// 創建主窗體
|
|
||||||
primaryForm = new PrimaryForm();
|
|
||||||
//primaryForm.allSongs = songListManager.AllSongs;
|
|
||||||
//primaryForm.allArtists = artistManager.AllArtists;
|
|
||||||
primaryForm.StartPosition = FormStartPosition.Manual;
|
|
||||||
primaryForm.Location = new Point(0, 0);
|
|
||||||
primaryForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
|
||||||
|
|
||||||
// 在完整初始化後檢查狀態
|
|
||||||
string stateFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"txt","states.txt");
|
|
||||||
bool isClosedState = File.Exists(stateFilePath) &&
|
|
||||||
File.ReadAllText(stateFilePath).Trim().Equals("CLOSE", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
InitializeSecondaryScreen();
|
|
||||||
|
|
||||||
// 使用 Shown 事件來確保窗體完全加載後再顯示送客畫面
|
|
||||||
if (isClosedState)
|
|
||||||
{
|
|
||||||
primaryForm.Shown += (s, e) =>
|
|
||||||
{
|
{
|
||||||
primaryForm.ShowSendOffScreen();
|
// 先送一次心跳 (同步呼叫)
|
||||||
};
|
sender.SendHeartbeatAsync().GetAwaiter().GetResult();
|
||||||
}
|
|
||||||
|
|
||||||
primaryForm.Show();
|
// 背景持續每3秒送心跳
|
||||||
Application.Run(primaryForm);
|
_ = Task.Run(async () =>
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
while (true)
|
||||||
{
|
{
|
||||||
WriteLog(ex.ToString());
|
await sender.SendHeartbeatAsync();
|
||||||
}
|
await Task.Delay(3000); // 每3秒送一次
|
||||||
finally
|
}
|
||||||
{
|
});
|
||||||
SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("登入失敗,無法送出心跳");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// COM 初始化
|
||||||
|
int hr = ComInterop.CoInitializeEx(IntPtr.Zero, ComInterop.COINIT_APARTMENTTHREADED);
|
||||||
|
if (hr < 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Failed to initialize COM library.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 初始化管理器
|
||||||
|
|
||||||
|
songListManager = new SongListManager(); // 使用单例
|
||||||
|
//artistManager = new ArtistManager();
|
||||||
|
|
||||||
|
var commandHandler = new CommandHandler(songListManager);
|
||||||
|
serialPortManager = new SerialPortManager(commandHandler);
|
||||||
|
serialPortManager.InitializeSerialPort();
|
||||||
|
|
||||||
|
// 輸出屏幕信息
|
||||||
|
Console.WriteLine($"Virtual Screen: {SystemInformation.VirtualScreen}");
|
||||||
|
foreach (var screen in Screen.AllScreens)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Screen: {screen.DeviceName} Resolution: {screen.Bounds.Width}x{screen.Bounds.Height}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 啟動服務器
|
||||||
|
Task.Run(() => HttpServerManager.StartServer());
|
||||||
|
Task.Run(() => TCPServerManager.StartServer());
|
||||||
|
|
||||||
|
// 註冊事件
|
||||||
|
Application.ApplicationExit += (sender, e) => SerialPortManager.CloseSerialPortSafely();
|
||||||
|
SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged;
|
||||||
|
|
||||||
|
// 創建主窗體
|
||||||
|
primaryForm = new PrimaryForm();
|
||||||
|
//primaryForm.allSongs = songListManager.AllSongs;
|
||||||
|
//primaryForm.allArtists = artistManager.AllArtists;
|
||||||
|
primaryForm.StartPosition = FormStartPosition.Manual;
|
||||||
|
primaryForm.Location = new Point(0, 0);
|
||||||
|
primaryForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
||||||
|
|
||||||
|
// 在完整初始化後檢查狀態
|
||||||
|
string stateFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "txt", "states.txt");
|
||||||
|
bool isClosedState = File.Exists(stateFilePath) &&
|
||||||
|
File.ReadAllText(stateFilePath).Trim().Equals("CLOSE", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
InitializeSecondaryScreen();
|
||||||
|
|
||||||
|
// 使用 Shown 事件來確保窗體完全加載後再顯示送客畫面
|
||||||
|
if (isClosedState)
|
||||||
|
{
|
||||||
|
primaryForm.Shown += (s, e) =>
|
||||||
|
{
|
||||||
|
primaryForm.ShowSendOffScreen();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
primaryForm.Show();
|
||||||
|
Application.Run(primaryForm);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
WriteLog(ex.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,9 +176,6 @@
|
|||||||
<Compile Update="PrimaryFormParts\SingerSearch\PrimaryForm.SingerSearch.PinyinSearch.cs">
|
<Compile Update="PrimaryFormParts\SingerSearch\PrimaryForm.SingerSearch.PinyinSearch.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="PrimaryFormParts\SingerSearch\PrimaryForm.SingerSearch.StrokeCountSearch.cs">
|
|
||||||
<SubType>Form</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="PrimaryFormParts\SingerSearch\PrimaryForm.SingerSearch.WordCountSearch.cs">
|
<Compile Update="PrimaryFormParts\SingerSearch\PrimaryForm.SingerSearch.WordCountSearch.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user