Aké riešenie ste použili na prácu s WebSocket?
sobes.tech AI
Odpoveď od AI
V projektoch, kde bola požadovaná obojsmerná komunikácia v reálnom čase, som úspešne použil URLSessionWebSocketTask.
Je to vstavané riešenie rámca Network, dostupné od iOS 13.
Výhody URLSessionWebSocketTask:
- Nativita: Integrované s
URLSession, čo zjednodušuje správu spojení a spracovanie sieťových udalostí. - Výkon: Optimalizované pre sieťovú komunikáciu na úrovni systému.
- Spoľahlivosť: Vstavaný mechanizmus pingov a pongov, automatické pokusy o opätovné pripojenie (hoci môže byť potrebná dodatočná logika pre zložité scenáre).
- Bezpečnosť: Podporuje TLS priamo z krabice.
Hlavné kroky práce:
-
Vytvorenie inštancie
URLSessionWebSocketTask.// Vytvorenie inštancie URLSession s predvolenými nastaveniami let session = URLSession(configuration: .default) // Inicializácia WebSocket úlohy let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!) -
Spustenie spojenia.
// Obnovenie úlohy na nadviazanie spojenia webSocketTask.resume() -
Odosielanie správ (textové alebo binárne dáta).
// Odoslanie textovej správy webSocketTask.send(.string("Hello, world!")) { error in if let error = error { print("Chyba pri odosielaní: \(error)") } } // Odoslanie binárnych dát let dataToSend = Data([1, 2, 3]) webSocketTask.send(.data(dataToSend)) { error in if let error = error { print("Chyba pri odosielaní: \(error)") } } -
Prijímanie správ. Je to asynchrónny proces.
// Rekurzívna funkcia na prijímanie správ func receiveMessage() { webSocketTask.receive { result in switch result { case .failure(let error): print("Chyba pri prijímaní: \(error)") // Spracovanie chyby, možno pokus o opätovné pripojenie case .success(let message): switch message { case .string(let text): print("Prijatá textová správa: \(text)") case .data(let data): print("Prijaté binárne dáta: \(data)") @unknown default: fatalError("Neznámy typ správy") } // Pokračujeme v počúvaní správ self.receiveMessage() } } } // Spustenie počúvania receiveMessage() -
Spracovanie udalostí životného cyklu spojenia (otvorenie, zatvorenie, chyby) s použitím delegáta
URLSessionWebSocketDelegate.// Príklad implementácie delegáta class WebSocketHandler: NSObject, URLSessionWebSocketDelegate { func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) { print("Spojenie otvorené") // Spustenie prijímania správ po otvorení receiveMessage() // Predpokladá sa, že receiveMessage je definovaná } func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) { let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Neznámy dôvod" print("Spojenie zatvorené s kódom \(closeCode.rawValue), dôvod: \(reasonString)") // Logika opätovného pripojenia alebo ukončenia práce } // Spracovanie chýb relácie func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { print("Úloha ukončená s chybou: \(error)") // Dodatočná logika spracovania chýb } } } // Pri vytváraní relácie použiť delegáta let delegate = WebSocketHandler() let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue()) let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
Použil som tiež tretie strany knižnice, ako je Starscream, keď bola požadovaná podpora starších verzií iOS alebo určité funkcie, ktoré chýbali v natívnom riešení (napríklad automatické opätovné pripojenie s exponenciálnou spätnou väzbou). Avšak, ak je to možné, uprednostňoval som URLSessionWebSocketTask kvôli vyššie uvedeným výhodám.