forked from AcaMate/AcaMate_iOS
120 lines
3.5 KiB
Swift
120 lines
3.5 KiB
Swift
//
|
|
// 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)")
|
|
}
|
|
}
|