Ответ
URLSessionDataTask — это задача для выполнения одноразовых HTTP/HTTPS-запросов по модели "запрос-ответ". Соединение устанавливается, данные передаются, и затем оно закрывается.
WebSocketTask (через URLSession) — это задача для установки двустороннего (full-duplex) постоянного соединения по протоколу WebSocket (ws:// или wss://). После "рукопожатия" (handshake) канал остается открытым для обмена сообщениями в реальном времени.
Сравнительная таблица:
| Аспект | URLSessionDataTask | WebSocketTask |
|---|---|---|
| Модель связи | Запрос-ответ (Request-Response) | Постоянное двустороннее соединение |
| Инициатор | Всегда клиент | Любая сторона (клиент или сервер) может отправить данные в любой момент |
| Протокол | HTTP/HTTPS | WebSocket (поверх TCP, начинается как HTTP) |
| Накладные расходы | Заголовки HTTP с каждым запросом | Минимальные, после установки соединения передается только payload |
| Типичное использование | Загрузка данных REST API, изображений, JSON | Чат, онлайн-игры, биржевые тикеры, коллаборативные приложения |
Пример WebSocket в Swift:
import Foundation
class WebSocketManager: NSObject, URLSessionWebSocketDelegate {
private var webSocketTask: URLSessionWebSocketTask?
func connect() {
let url = URL(string: "wss://echo.websocket.events")!
let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
webSocketTask = session.webSocketTask(with: url)
webSocketTask?.resume()
receiveMessage() // Начинаем слушать сообщения
}
func send(_ message: String) {
let message = URLSessionWebSocketTask.Message.string(message)
webSocketTask?.send(message) { error in
if let error = error { print("Send error: ", error) }
}
}
private func receiveMessage() {
webSocketTask?.receive { [weak self] result in
switch result {
case .success(let message):
switch message {
case .string(let text):
print("Received: ", text)
case .data(let data):
print("Received data: ", data)
@unknown default:
break
}
self?.receiveMessage() // Рекурсивно слушаем следующее сообщение
case .failure(let error):
print("Receive error: ", error)
}
}
}
func disconnect() {
webSocketTask?.cancel(with: .normalClosure, reason: nil)
}
}
Пример DataTask:
func fetchData(from url: URL, completion: @escaping (Result<Data, Error>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else { return }
completion(.success(data))
}.resume()
}