// // WebSocketManager.swift // AcaMate // // Created by TAnine on 2/17/25. // import Foundation import Combine import Starscream // SignalR은 메세지의 끝이 \u{1E} 해당 유니코드 문자를 원함 class WebSocketManager: ObservableObject ,WebSocketDelegate { @Published var socket: WebSocket? @Published var receivedMessage: [String] = [] init() { guard let url = URL(string: "\(WS_URL)/chatHub?transport=webSockets") else { return } var request = URLRequest(url: url) request.timeoutInterval = 5 request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("Upgrade", forHTTPHeaderField: "Connection") socket = WebSocket(request: request) socket?.delegate = self } func connect() { printLog("TRY CONNECT SOCKET") socket?.connect() } func didReceive(event: Starscream.WebSocketEvent, client: WebSocketClient) { switch event { case .connected(let header): printLog("CONNECTED : \(header)") // 우리는 현재 JSON기반으로 메시지를 주고 받을거고 SignalR JSON 프로토콜의 버전은 1이다 let handShakeMsg = """ { "protocol":"json", "version":1 }\u{1E} """ self.socket?.write(string: handShakeMsg) case .disconnected(let reason, let code): printLog("❌ DISCONNECTED: [\(code)] - \(reason)") case .error(let error): printLog("🆘 SOCKET ERROR: \(error?.localizedDescription ?? "unknown")") case .text(let text): // 서버에서 메세지를 보내면 여기로 들어올거고 // 받아온 텍스트의 앞은 target, [sendet, message] 순서로 들어온다. printLog("📩 SERVER SENT: \(text)") if let data = try? JSONSerialization.jsonObject(with: Data(text.utf8)) as? [String: Any], let target = data["target"] as? String, let args = data["arguments"] as? [String] { if target == "ReceiveMessage" { let sender = args[0] let message = args[1] receivedMessage.append(message) print("💬 [\(sender)] \(message)") } } case .binary(let binary): printLog("BINARY?: \(binary)") case .cancelled: printLog("SOCKET CONNECTED CANCELLED!!!") default: break } } func disconnect() { socket?.disconnect() socket?.delegate = nil // 추가: delegate 해제 socket = nil // 필요시, 소켓 객체 해제 printLog("CLOSE SOCKET") } func sendMessage(_ message: String) { let json = """ { "type": 1, "target":"SendMessage", "arguments":["iOS", "\(message)"] }\u{1E} """ socket?.write(string: json) printLog("SEND THE MESSAGE: \(message)") } func joinRoom(_ cid: String){ let json = """ { "type": 1, "target":"JoinRoom", "arguments":["\(cid)"] }\u{1E} """ socket?.write(string: json) printLog("JOIN: \(cid)") } }