using System; using System.ServiceProcess; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; namespace NoticeServer { public partial class NoticeService : ServiceBase { private CancellationTokenSource _cancellationTokenSource; private Task _serviceTask; private static TcpChatServer _tcpServer; public NoticeService() { InitializeComponent(); ServiceName = "EETGWNoticeService"; CanStop = true; CanPauseAndContinue = false; AutoLog = true; } protected override void OnStart(string[] args) { try { EventLog.WriteEntry(ServiceName, "Notice 서비스가 시작됩니다.", EventLogEntryType.Information); _cancellationTokenSource = new CancellationTokenSource(); _serviceTask = Task.Run(() => DoWork(_cancellationTokenSource.Token)); EventLog.WriteEntry(ServiceName, "Notice 서비스가 성공적으로 시작되었습니다.", EventLogEntryType.Information); } catch (Exception ex) { EventLog.WriteEntry(ServiceName, $"서비스 시작 중 오류 발생: {ex.Message}", EventLogEntryType.Error); throw; } } protected override void OnStop() { try { EventLog.WriteEntry(ServiceName, "Notice 서비스를 중지합니다.", EventLogEntryType.Information); _cancellationTokenSource?.Cancel(); // Stop server _tcpServer?.Stop(); if (_serviceTask != null) { // 최대 30초 대기 if (!_serviceTask.Wait(TimeSpan.FromSeconds(30))) { EventLog.WriteEntry(ServiceName, "서비스 중지 시간 초과", EventLogEntryType.Warning); } } EventLog.WriteEntry(ServiceName, "Notice 서비스가 중지되었습니다.", EventLogEntryType.Information); } catch (Exception ex) { EventLog.WriteEntry(ServiceName, $"서비스 중지 중 오류 발생: {ex.Message}", EventLogEntryType.Error); } finally { _cancellationTokenSource?.Dispose(); _serviceTask?.Dispose(); } } private void DoWork(CancellationToken cancellationToken) { EventLog.WriteEntry(ServiceName, "Notice 서비스 작업을 시작합니다.", EventLogEntryType.Information); try { // Read settings int tcpPort = Properties.Settings.Default.TcpPort; int maxClients = Properties.Settings.Default.MaxClients; // Start server _tcpServer = new TcpChatServer(tcpPort, maxClients); _tcpServer.Start(); EventLog.WriteEntry(ServiceName, $"Notice 서버가 포트 {tcpPort}에서 시작되었습니다.", EventLogEntryType.Information); // Wait for cancellation while (!cancellationToken.IsCancellationRequested) { if (cancellationToken.WaitHandle.WaitOne(1000)) { break; // 취소 요청 시 종료 } } } catch (Exception ex) { EventLog.WriteEntry(ServiceName, $"서버 실행 중 오류 발생: {ex.Message}\n{ex.StackTrace}", EventLogEntryType.Error); } EventLog.WriteEntry(ServiceName, "Notice 서비스 작업이 종료되었습니다.", EventLogEntryType.Information); } private void InitializeComponent() { // // NoticeService // this.ServiceName = "EETGWNoticeService"; } } }