using System; using WebSocketSharp; using WebSocketSharp.Server; using UnityEngine; namespace KindRetargeting.Remote { /// /// WebSocket 서버 - 실시간 양방향 통신을 담당합니다. /// public class RetargetingWebSocketServer { private WebSocketServer wss; private int port; private bool isRunning = false; public bool IsRunning => isRunning; public int Port => port; public event Action OnMessageReceived; public RetargetingWebSocketServer(int port) { this.port = port; } public void Start() { if (isRunning) return; try { wss = new WebSocketServer(port); wss.AddWebSocketService("/retargeting", behavior => { behavior.OnMessageReceivedCallback = (msg) => OnMessageReceived?.Invoke(msg); }); wss.Start(); isRunning = true; Debug.Log($"[RetargetingWS] WebSocket 서버 시작됨 (포트: {port})"); } catch (Exception ex) { Debug.LogError($"[RetargetingWS] 서버 시작 실패: {ex.Message}"); } } public void Stop() { if (!isRunning) return; try { wss?.Stop(); } catch (Exception) { } isRunning = false; Debug.Log("[RetargetingWS] WebSocket 서버 중지됨"); } public void Broadcast(string message) { if (!isRunning || wss == null) return; try { wss.WebSocketServices["/retargeting"].Sessions.Broadcast(message); } catch (Exception ex) { Debug.LogError($"[RetargetingWS] 브로드캐스트 실패: {ex.Message}"); } } /// /// WebSocket 동작 핸들러 /// private class RetargetingBehavior : WebSocketBehavior { public Action OnMessageReceivedCallback; protected override void OnOpen() { // 연결 시 로그 제거 (문서 요청에 따름) } protected override void OnClose(CloseEventArgs e) { // 연결 종료 시 로그 제거 } protected override void OnMessage(MessageEventArgs e) { // 로그 제거 (문서 요청에 따름) OnMessageReceivedCallback?.Invoke(e.Data); } protected override void OnError(ErrorEventArgs e) { Debug.LogError($"[RetargetingWS] 오류: {e.Message}"); } } } }