В чем разница между WebSocket и сокетом (Socket) в iOS?

Ответ

WebSocket — это высокоуровневый протокол поверх TCP, обеспечивающий постоянное полнодуплексное соединение между клиентом и сервером. Он работает поверх HTTP, используя начальное рукопожатие (handshake) для установки соединения, после чего обмен данными происходит в виде фреймов без HTTP-заголовков.

Socket (сокет) — это низкоуровневый программный интерфейс (API) для сетевого взаимодействия по протоколам TCP или UDP. Требует ручного управления подключением, сериализацией данных, обработкой ошибок и поддержанием соединения.

Ключевые отличия:

Аспект WebSocket Socket (Network framework)
Уровень Протокол прикладного уровня (поверх HTTP) Транспортный уровень (TCP/UDP)
Сложность Высокоуровневый, встроенная поддержка в URLSession Низкоуровневый, требуется ручная реализация
Данные Обмен сообщениями или фреймами Работа с потоками байтов (Data)
Состояние Управление соединением встроено в протокол Требуется ручной контроль состояния

Пример WebSocket (Swift):

let url = URL(string: "wss://echo.websocket.org")!
let webSocketTask = URLSession.shared.webSocketTask(with: url)
webSocketTask.resume()

// Отправка сообщения
webSocketTask.send(.string("Hello WebSocket")) { error in
    if let error = error { print("Send error: (error)") }
}

// Получение сообщений
func receiveMessage() {
    webSocketTask.receive { 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
            }
        case .failure(let error): print("Receive error: (error)")
        }
        self.receiveMessage() // Продолжаем слушать
    }
}

Пример TCP Socket (Swift, Network framework):

import Network

let connection = NWConnection(host: "example.com", port: 80, using: .tcp)
connection.stateUpdateHandler = { newState in
    switch newState {
    case .ready:
        print("Socket connected")
        let data = "Hello Socketn".data(using: .utf8)!
        connection.send(content: data, completion: .idempotent)
    case .failed(let error): print("Connection failed: (error)")
    default: break
    }
}

connection.start(queue: .main)

Когда использовать:

  • WebSocket — для реального времени (чаты, уведомления, биржевые тикеры), когда нужен стандартный протокол поверх HTTP/HTTPS.
  • Сокеты — для кастомных протоколов, высокой производительности, P2P-соединений или когда требуется полный контроль над сетевым стеком.

Ответ 18+ 🔞

Давай разберём эту дичь, чтобы не путать горячее с мягким. Вот смотри, есть два способа общаться по сети, и один из них — для ленивых, а второй — для тех, кто любит всё контролировать до последнего байта.

WebSocket — это как взять обычный HTTP и прокачать его стероидами. Сначала он скромно стучится к серверу, как обычный веб-запрос (рукопожатие, блядь), а потом — бац! — и они остаются на связи насовсем. Канал открыт, и можно туда-сюда слать сообщения без этих ёбаных HTTP-заголовков каждый раз. Удобно, высокоуровнево.

Socket (или просто сокет) — это уже не протокол, а голый, босоногий инструмент. Это как тебе дали паяльник, моток проводов и сказали: «Собери себе связь, мудила». Работаешь напрямую с TCP или UDP, сам управляешь подключением, сам разбираешь поток байтов, сам всё. Контроль полный, но и возни — овердохуища.

Короче, в чём разница:

Штука WebSocket Socket (Network framework)
Уровень крутости Высокоуровневый протокол, почти как готовая библиотека. Низкоуровневый API, сам себе сантехник.
Сложность Для людей. Всё уже прикручено. Для гиков и мазохистов. Всё надо пилить самому.
Что летает Сообщения или фреймы. Просто поток байтов, Data, а что в них — твои проблемы.
Контроль Соединением управляет протокол. Состояние соединения, таймауты, переподключения — всё на твоей совести, чувак.

Вот как выглядит жизнь с WebSocket (Swift):

let url = URL(string: "wss://echo.websocket.org")!
let webSocketTask = URLSession.shared.webSocketTask(with: url)
webSocketTask.resume()

// Шлём привет
webSocketTask.send(.string("Hello WebSocket")) { error in
    if let error = error { print("Send error: (error)") }
}

// Сидим, слушаем, что нам пришлют
func receiveMessage() {
    webSocketTask.receive { 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
            }
        case .failure(let error): print("Receive error: (error)")
        }
        self.receiveMessage() // И так до скончания времён
    }
}

А вот как выглядит ад с обычными сокетами (Swift, Network framework):

import Network

let connection = NWConnection(host: "example.com", port: 80, using: .tcp)
connection.stateUpdateHandler = { newState in
    switch newState {
    case .ready:
        print("Socket connected")
        let data = "Hello Socketn".data(using: .utf8)!
        connection.send(content: data, completion: .idempotent)
    case .failed(let error): print("Connection failed: (error)")
    default: break
    }
}

connection.start(queue: .main)

Так когда что использовать, чтобы не облажаться?

  • WebSocket — твой выбор, если делаешь что-то в реальном времени: чат, уведомления, онлайн-игру, биржевой тикер. Когда нужно, чтобы всё просто работало поверх обычного HTTPS, и не хочется изобретать свой велосипед.
  • Сырые сокеты — бери в руки, если пишешь свой кастомный протокол, делаешь P2P-сеть, файлообменник или тебе критически важна каждая миллисекунда и каждый байт. Когда готов париться с буферами, таймаутами и переподключениями.