Sobes.tech
Middle

Milyen megoldást használtál a WebSocket kezelésére?

sobes.tech MI

Válasz az MI-től

Olyan projektekben, ahol valós idejű kétirányú kommunikáció volt szükséges, sikeresen használtam a URLSessionWebSocketTask-t.

Ez a Network keretrendszer beépített megoldása, az iOS 13-tól elérhető.

A URLSessionWebSocketTask előnyei:

  • Natív: Integrálva a URLSession-nel, ami megkönnyíti a kapcsolatok kezelését és a hálózati események feldolgozását.
  • Teljesítmény: A rendszer szintjén optimalizált hálózati működésre.
  • Megbízhatóság: Beépített ping és pong mechanizmus, automatikus újracsatlakozási kísérletek (bár összetettebb szcenáriókhoz további logika szükséges lehet).
  • Biztonság: Out-of-the-box TLS támogatás.

Fő lépések:

  1. A URLSessionWebSocketTask példányának létrehozása.

    // Alapértelmezett beállításokkal rendelkező URLSession példány létrehozása
    let session = URLSession(configuration: .default)
    // WebSocket feladat inicializálása
    let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    
  2. A kapcsolat indítása.

    // A feladat folytatása a kapcsolat létrehozásához
    webSocketTask.resume()
    
  3. Üzenetek küldése (szöveg vagy bináris adatok).

    // Szöveges üzenet küldése
    webSocketTask.send(.string("Hello, world!")) { error in
        if let error = error {
            print("Hiba küldés közben: \(error)")
        }
    }
    
    // Bináris adatok küldése
    let dataToSend = Data([1, 2, 3])
    webSocketTask.send(.data(dataToSend)) { error in
        if let error = error {
            print("Hiba küldés közben: \(error)")
        }
    }
    
  4. Üzenetek fogadása. Ez egy aszinkron folyamat.

    // Rekurzív függvény az üzenetek fogadására
    func receiveMessage() {
        webSocketTask.receive { result in
            switch result {
            case .failure(let error):
                print("Hiba fogadás közben: \(error)")
                // Hiba kezelése, esetleg újracsatlakozás
            case .success(let message):
                switch message {
                case .string(let text):
                    print("Kapott szöveges üzenet: \(text)")
                case .data(let data):
                    print("Kapott bináris adatok: \(data)")
                @unknown default:
                    fatalError("Ismeretlen üzenettípus")
                }
                // Folytatjuk az üzenetek hallgatását
                self.receiveMessage()
            }
        }
    }
    
    // Indítsuk el a hallgatót
    receiveMessage()
    
  5. A kapcsolat életciklus eseményeinek kezelése (URLSessionWebSocketDelegate használatával).

    // Példa delegátum implementáció
    class WebSocketHandler: NSObject, URLSessionWebSocketDelegate {
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
            print("Kapcsolat nyitva")
            // Az üzenetek fogadásának megkezdése a nyitás után
            receiveMessage() // feltételezve, hogy a receiveMessage definiálva van
        }
    
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
            let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Ismeretlen ok"
            print("Kapcsolat lezárva kóddal \(closeCode.rawValue), ok: \(reasonString)")
            // Újracsatlakozási vagy befejezési logika
        }
    
        // A szekció hibáinak kezelése
        func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
            if let error = error {
                print("Feladat hibával ért véget: \(error)")
                // További hibakezelő logika
            }
        }
    }
    
    // A szekció létrehozásakor a delegátust használjuk
    let delegate = WebSocketHandler()
    let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue())
    let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    

Emellett külső könyvtárakat is használtam, például a Starscream-et, amikor régebbi iOS verziók támogatása vagy bizonyos funkciók, például az automatikus újracsatlakozás exponenciális visszaeséssel, szükséges volt. Azonban, ha lehetséges, előnyben részesítettem a URLSessionWebSocketTask-t a fent említett előnyök miatt.