¿Qué solución utilizaste para trabajar con WebSocket?
sobes.tech AI
Respuesta de la IA
En proyectos que requerían interacción bidireccional en tiempo real, utilicé con éxito URLSessionWebSocketTask.
Esta es una solución integrada del framework Network, disponible desde iOS 13.
Ventajas de URLSessionWebSocketTask:
- Nativo: Integrado con
URLSession, lo que simplifica la gestión de conexiones y el manejo de eventos de red. - Rendimiento: Optimizado para trabajar con la red a nivel del sistema.
- Fiabilidad: Mecanismo incorporado de pings y pongs, intentos automáticos de reconexión (aunque puede requerir lógica adicional para escenarios complejos).
- Seguridad: Soporta TLS de serie.
Etapas principales de trabajo:
-
Crear una instancia de
URLSessionWebSocketTask.// Crear una instancia de URLSession con configuración predeterminada let session = URLSession(configuration: .default) // Inicializar la tarea WebSocket let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!) -
Iniciar la conexión.
// Reanudar la tarea para establecer la conexión webSocketTask.resume() -
Enviar mensajes (texto o datos binarios).
// Enviar un mensaje de texto webSocketTask.send(.string("Hello, world!")) { error in if let error = error { print("Error al enviar: \(error)") } } // Enviar datos binarios let dataToSend = Data([1, 2, 3]) webSocketTask.send(.data(dataToSend)) { error in if let error = error { print("Error al enviar: \(error)") } } -
Recepción de mensajes. Es un proceso asíncrono.
// Función recursiva para recibir mensajes func receiveMessage() { webSocketTask.receive { result in switch result { case .failure(let error): print("Error al recibir: \(error)") // Manejar error, posiblemente reintentar conexión case .success(let message): switch message { case .string(let text): print("Mensaje de texto recibido: \(text)") case .data(let data): print("Datos binarios recibidos: \(data)") @unknown default: fatalError("Tipo de mensaje desconocido") } // Continuar escuchando mensajes self.receiveMessage() } } } // Iniciar escucha receiveMessage() -
Manejar eventos del ciclo de vida de la conexión (apertura, cierre, errores) usando el delegado
URLSessionWebSocketDelegate.// Ejemplo de implementación del delegado class WebSocketHandler: NSObject, URLSessionWebSocketDelegate { func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) { print("Conexión abierta") // Iniciar recepción de mensajes tras apertura receiveMessage() // Se asume que receiveMessage está definido } func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) { let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Razón desconocida" print("Conexión cerrada con código \(closeCode.rawValue), razón: \(reasonString)") // Lógica de reconexión o cierre } // Manejar errores de la sesión func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { print("Tarea finalizada con error: \(error)") // Lógica adicional de manejo de errores } } } // Al crear la sesión, usar el delegado let delegate = WebSocketHandler() let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue()) let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
También he utilizado bibliotecas de terceros, como Starscream, cuando se requería soporte para versiones más antiguas de iOS o funcionalidades específicas no disponibles en la solución nativa (por ejemplo, reconexión automática con retroceso exponencial). Sin embargo, cuando era posible, prefería URLSessionWebSocketTask por las ventajas mencionadas anteriormente.