Koje rešenje ste koristili za rad sa WebSocket?
sobes.tech АИ
Одговор од АИ
У пројектима где је била потребна двосмерна комуникација у реалном времену, успешно сам користио
URLSessionWebSocketTask.
Ово је уграђено решење из фрејмворка Network, доступно од iOS 13.
Предности URLSessionWebSocketTask:
- Нативно: Интегрисано са
URLSession, што олакшава управљање везама и обраду мрежних догађаја. - Перформансе: Оптимизовано за рад са мрежом на нивоу система.
- Поузданост: Уграђени механизам пинг и пинг, аутоматски покушаји поновног повезивања (иако може бити потребна додатна логика за сложеније сценарије).
- Безбедност: Подржава TLS из кутије.
Главни кораци:
-
Креирање инстанце
URLSessionWebSocketTask.// Креирање инстанце URLSession са подразумеваним подешавањима let session = URLSession(configuration: .default) // Инициализација WebSocket задатка let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!) -
Покретање везе.
// Настављање задатка за успостављање везе webSocketTask.resume() -
Слање порука (текстуалних или бинарних података).
// Слање текстуалне поруке webSocketTask.send(.string("Hello, world!")) { error in if let error = error { print("Грешка при слању: \(error)") } } // Слање бинарних података let dataToSend = Data([1, 2, 3]) webSocketTask.send(.data(dataToSend)) { error in if let error = error { print("Грешка при слању: \(error)") } } -
Примање порука. Ово је асинхрона процес.
// Рекурсивна функција за примање порука func receiveMessage() { webSocketTask.receive { result in switch result { case .failure(let error): print("Грешка при пријему: \(error)") // Обрада грешке, могуће покушај поновног повезивања case .success(let message): switch message { case .string(let text): print("Примљена текстуална порука: \(text)") case .data(let data): print("Примљени бинарни подаци: \(data)") @unknown default: fatalError("Непознат тип поруке") } // Настављамо слушање порука self.receiveMessage() } } } // Покретање слушача receiveMessage() -
Обрада догађаја животног циклуса везе (отварање, затварање, грешке) коришћењем делегата
URLSessionWebSocketDelegate.// Пример имплементације делегата class WebSocketHandler: NSObject, URLSessionWebSocketDelegate { func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) { print("Веза отворена") // Почетак слушања порука након отварања receiveMessage() // претпоставља се да је receiveMessage дефинисан } func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) { let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Непознат разлог" print("Веза затворена са кодом \(closeCode.rawValue), разлог: \(reasonString)") // Логика поновног повезивања или завршетка } // Обрада грешака сесије func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { print("Завршетак задатка са грешком: \(error)") // Додатна логика обраде грешака } } } // При креирању сесије користити делегата let delegate = WebSocketHandler() let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue()) let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
Такође сам користио библиотеке трећих страна као што је Starscream, када је била потребна подршка за старије верзије iOS или одређене функционалности које нису доступне у нативном решењу (нпр. аутоматско поновно повезивање са експоненцијалним закашњењем). Међутим, ако је могуће, преферирао сам URLSessionWebSocketTask због горе наведених предности.