Sobes.tech
Middle

What solution did you use for working with WebSocket?

sobes.tech AI

Answer from AI

In projects where real-time two-way interaction was required, I successfully used URLSessionWebSocketTask.

This is a built-in solution of the Network framework, available starting from iOS 13.

Advantages of URLSessionWebSocketTask:

  • Native: Integrated with URLSession, which simplifies connection management and network event handling.
  • Performance: Optimized for network operations at the system level.
  • Reliability: Built-in ping and pong mechanisms, automatic reconnection attempts (though additional logic may be needed for complex scenarios).
  • Security: Supports TLS out of the box.

Main steps of operation:

  1. Creating an instance of URLSessionWebSocketTask.

    // Creating a URLSession instance with default settings
    let session = URLSession(configuration: .default)
    // Initializing WebSocket task
    let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    
  2. Starting the connection.

    // Resuming the task to establish the connection
    webSocketTask.resume()
    
  3. Sending messages (text or binary data).

    // Sending a text message
    webSocketTask.send(.string("Hello, world!")) { error in
        if let error = error {
            print("Send error: \(error)")
        }
    }
    
    // Sending binary data
    let dataToSend = Data([1, 2, 3])
    webSocketTask.send(.data(dataToSend)) { error in
        if let error = error {
            print("Send error: \(error)")
        }
    }
    
  4. Receiving messages. This is an asynchronous process.

    // Recursive function to receive messages
    func receiveMessage() {
        webSocketTask.receive { result in
            switch result {
            case .failure(let error):
                print("Receive error: \(error)")
                // Handle error, possibly attempt reconnection
            case .success(let message):
                switch message {
                case .string(let text):
                    print("Received text message: \(text)")
                case .data(let data):
                    print("Received binary data: \(data)")
                @unknown default:
                    fatalError("Unknown message type")
                }
                // Continue listening for messages
                self.receiveMessage()
            }
        }
    }
    
    // Start listening
    receiveMessage()
    
  5. Handling connection lifecycle events (open, close, errors) using the URLSessionWebSocketDelegate delegate.

    // Delegate implementation example
    class WebSocketHandler: NSObject, URLSessionWebSocketDelegate {
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
            print("Connection opened")
            // Start receiving messages after opening
            receiveMessage() // Assumes receiveMessage is defined
        }
    
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
            let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Unknown reason"
            print("Connection closed with code \(closeCode.rawValue), reason: \(reasonString)")
            // Reconnection logic or cleanup
        }
    
        // Session error handling
        func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
            if let error = error {
                print("Task completed with error: \(error)")
                // Additional error handling logic
            }
        }
    }
    
    // When creating the session, use the delegate
    let delegate = WebSocketHandler()
    let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue())
    let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    

I also used third-party libraries like Starscream when support for older iOS versions or certain features not available in the native solution (such as automatic reconnection with exponential backoff) was required. However, when possible, I preferred URLSessionWebSocketTask due to the advantages mentioned above.

What solution did you use for working with WebSocket… - sobes.tech