Qual solução você usou para trabalhar com WebSocket?
sobes.tech IA
Resposta da IA
Nos projetos que requeriam interação bidirecional em tempo real, utilizei com sucesso URLSessionWebSocketTask.
Esta é uma solução integrada do framework Network, disponível desde o iOS 13.
Vantagens do URLSessionWebSocketTask:
- Nativo: Integrado com
URLSession, o que simplifica a gestão de conexões e o tratamento de eventos de rede. - Performance: Otimizado para trabalhar com a rede ao nível do sistema.
- Confiabilidade: Mecanismo embutido de pings e pongs, tentativas automáticas de reconexão (embora possa ser necessária lógica adicional para cenários complexos).
- Segurança: Suporta TLS de série.
Etapas principais:
-
Criar uma instância de
URLSessionWebSocketTask.// Criar uma instância de URLSession com configuração padrão let session = URLSession(configuration: .default) // Inicializar a tarefa WebSocket let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!) -
Iniciar a conexão.
// Recomeçar a tarefa para estabelecer a conexão webSocketTask.resume() -
Enviar mensagens (texto ou dados binários).
// Enviar uma mensagem de texto webSocketTask.send(.string("Hello, world!")) { error in if let error = error { print("Erro ao enviar: \(error)") } } // Enviar dados binários let dataToSend = Data([1, 2, 3]) webSocketTask.send(.data(dataToSend)) { error in if let error = error { print("Erro ao enviar: \(error)") } } -
Receber mensagens. É um processo assíncrono.
// Função recursiva para receber mensagens func receiveMessage() { webSocketTask.receive { result in switch result { case .failure(let error): print("Erro ao receber: \(error)") // Lidar com erro, possivelmente tentar reconectar case .success(let message): switch message { case .string(let text): print("Mensagem de texto recebida: \(text)") case .data(let data): print("Dados binários recebidos: \(data)") @unknown default: fatalError("Tipo de mensagem desconhecido") } // Continuar ouvindo mensagens self.receiveMessage() } } } // Iniciar ouvindo receiveMessage() -
Gerenciar eventos do ciclo de vida da conexão (abertura, fechamento, erros) usando o delegado
URLSessionWebSocketDelegate.// Exemplo de implementação do delegado class WebSocketHandler: NSObject, URLSessionWebSocketDelegate { func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) { print("Conexão aberta") // Iniciar recebimento de mensagens após abertura receiveMessage() // Presume-se 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ão desconhecida" print("Conexão fechada com código \(closeCode.rawValue), razão: \(reasonString)") // Lógica de reconexão ou encerramento } // Lidar com erros de sessão func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { print("Tarefa finalizada com erro: \(error)") // Lógica adicional de tratamento de erros } } } // Ao criar a sessão, usar o delegado let delegate = WebSocketHandler() let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue()) let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
Também utilizei bibliotecas de terceiros, como Starscream, quando era necessário suporte para versões mais antigas do iOS ou funcionalidades específicas não disponíveis na solução nativa (por exemplo, reconexão automática com atraso exponencial). No entanto, sempre que possível, preferi URLSessionWebSocketTask devido às vantagens acima mencionadas.