Sobes.tech
Middle

Welke oplossing heb je gebruikt voor het werken met WebSocket?

sobes.tech AI

Antwoord van AI

In projecten waar realtime tweerichtingscommunicatie vereist was, heb ik succesvol URLSessionWebSocketTask gebruikt.

Dit is een ingebouwde oplossing van het Network-framework, beschikbaar vanaf iOS 13.

Voordelen van URLSessionWebSocketTask:

  • Native: Geïntegreerd met URLSession, wat het beheer van verbindingen en het verwerken van netwerkgebeurtenissen vereenvoudigt.
  • Prestaties: Geoptimaliseerd voor netwerkwerking op systeemniveau.
  • Betrouwbaarheid: Ingebouwd ping- en pong-mechanisme, automatische reconnection pogingen (hoewel extra logica nodig kan zijn voor complexe scenario's).
  • Veiligheid: Ondersteunt TLS out-of-the-box.

Belangrijke stappen:

  1. Aanmaken van een URLSessionWebSocketTask-voorbeeld.

    // Aanmaken van een URLSession-voorbeeld met standaardinstellingen
    let session = URLSession(configuration: .default)
    // Initialiseren van WebSocket-taak
    let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    
  2. Verbinding starten.

    // Hervatten van de taak om de verbinding tot stand te brengen
    webSocketTask.resume()
    
  3. Berichten verzenden (tekst of binaire gegevens).

    // Verzenden van een tekstbericht
    webSocketTask.send(.string("Hello, world!")) { error in
        if let error = error {
            print("Fout bij verzenden: \(error)")
        }
    }
    
    // Verzenden van binaire gegevens
    let dataToSend = Data([1, 2, 3])
    webSocketTask.send(.data(dataToSend)) { error in
        if let error = error {
            print("Fout bij verzenden: \(error)")
        }
    }
    
  4. Ontvangen van berichten. Dit is een asynchrone proces.

    // Recursieve functie voor het ontvangen van berichten
    func receiveMessage() {
        webSocketTask.receive { result in
            switch result {
            case .failure(let error):
                print("Fout bij ontvangst: \(error)")
                // Foutafhandeling, mogelijk herverbinding proberen
            case .success(let message):
                switch message {
                case .string(let text):
                    print("Ontvangen tekstbericht: \(text)")
                case .data(let data):
                    print("Ontvangen binaire gegevens: \(data)")
                @unknown default:
                    fatalError("Onbekend berichttype")
                }
                // Blijf luisteren naar berichten
                self.receiveMessage()
            }
        }
    }
    
    // Start de luisterfunctie
    receiveMessage()
    
  5. Afhandelen van connectielevenscyclusgebeurtenissen (open, close, errors) met behulp van de URLSessionWebSocketDelegate.

    // Voorbeeld van delegate-implementatie
    class WebSocketHandler: NSObject, URLSessionWebSocketDelegate {
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
            print("Verbinding geopend")
            // Start met ontvangen van berichten na opening
            receiveMessage() // Veronderstelt dat receiveMessage gedefinieerd is
        }
    
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
            let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Onbekende reden"
            print("Verbinding gesloten met code \(closeCode.rawValue), reden: \(reasonString)")
            // Logica voor herverbinding of afsluiten
        }
    
        // Foutafhandeling van de sessie
        func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
            if let error = error {
                print("Taak beëindigd met fout: \(error)")
                // Extra foutafhandelingslogica
            }
        }
    }
    
    // Bij het aanmaken van de sessie delegeert gebruiken
    let delegate = WebSocketHandler()
    let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue())
    let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    

Ik heb ook externe bibliotheken gebruikt, zoals Starscream, wanneer ondersteuning voor oudere iOS-versies of bepaalde functies nodig was die niet in de native oplossing aanwezig zijn (bijvoorbeeld automatische herverbinding met exponentiële backoff). Echter, indien mogelijk, gaf ik de voorkeur aan URLSessionWebSocketTask vanwege de bovengenoemde voordelen.