Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
WebSocket — двусторонняя коммуникация в реальном времени
Что такое WebSocket
WebSocket — это протокол, который обеспечивает полнодуплексную (двусторонню) коммуникацию между клиентом и сервером через одно TCP соединение. В отличие от HTTP, это постоянное соединение.
HTTP vs WebSocket
HTTP (Request-Response):
Клиент → [Запрос] → Сервер
Клиент ← [Ответ] ← Сервер
(соединение закрывается)
Для каждого запроса нужно открывать новое соединение.
WebSocket (Persistent Connection):
Клиент ↔ [Соединение] ↔ Сервер
(одно соединение, двусторонний трафик)
Одно соединение для множества сообщений.
Как работает WebSocket
1. Handshake (HTTP upgrade):
Клиент отправляет:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
Сервер ответит:
101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
2. Persistent Connection:
- Соединение остаётся открыто
- Низкий overhead (нет HTTP headers)
3. Bidirectional Communication:
Время →
Клиент: "Hello"
Сервер: "Hi there!"
Клиент: "How are you?"
Сервер: "Fine, thanks!"
Реализация в iOS (URLSessionWebSocketTask)
import Foundation
class WebSocketManager {
var webSocket: URLSessionWebSocketTask?
func connect(to url: URL) {
let session = URLSession(configuration: .default)
webSocket = session.webSocketTask(with: url)
webSocket?.resume()
receiveMessage()
}
private func receiveMessage() {
webSocket?.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("WebSocket error: \(error)")
}
}
}
func send(_ message: String) {
let message = URLSessionWebSocketTask.Message.string(message)
webSocket?.send(message) { error in
if let error = error {
print("Send error: \(error)")
}
}
}
func disconnect() {
webSocket?.cancel(with: .goingAway, reason: nil)
}
}
Использование
let manager = WebSocketManager()
let url = URL(string: "wss://echo.websocket.org")! // wss = WebSocket Secure
manager.connect(to: url)
// Отправить сообщение
manager.send("Hello, Server!")
// Закрыть соединение
manager.disconnect()
Типы сообщений
// String (текст)
let stringMessage = URLSessionWebSocketTask.Message.string("Hello")
// Data (бинарные данные)
let data = "Hello".data(using: .utf8)!
let dataMessage = URLSessionWebSocketTask.Message.data(data)
// Отправить
webSocket?.send(stringMessage) { error in
// Handler
}
Ping-Pong (keep-alive)
func keepAlive() {
webSocket?.sendPing { error in
if let error = error {
print("Ping error: \(error)")
} else {
print("Ping sent")
}
}
}
// Автоматический ping каждые 30 секунд
Timer.scheduledTimer(withTimeInterval: 30, repeats: true) { [weak self] _ in
self?.keepAlive()
}.fire()
Обработка состояний соединения
enum WebSocketState {
case connecting
case connected
case disconnecting
case disconnected(Error?)
}
class WebSocketManager: NSObject {
@Published var state: WebSocketState = .disconnected(nil)
func connect(to url: URL) {
state = .connecting
// ...
}
private func receiveMessage() {
webSocket?.receive { [weak self] result in
switch result {
case .success:
self?.state = .connected
self?.receiveMessage()
case .failure(let error):
self?.state = .disconnected(error)
}
}
}
}
Реальный пример: чат приложение
@MainActor
class ChatViewModel: ObservableObject {
@Published var messages: [Message] = []
@Published var connectionStatus: String = "Disconnected"
private let webSocketManager = WebSocketManager()
func connect() {
let url = URL(string: "wss://chat-server.com/ws")!
webSocketManager.connect(to: url)
connectionStatus = "Connected"
}
func sendMessage(_ text: String) {
webSocketManager.send(text)
messages.append(Message(author: "Me", text: text))
}
func disconnect() {
webSocketManager.disconnect()
connectionStatus = "Disconnected"
}
}
Когда использовать WebSocket
✅ Чат приложения (real-time messaging) ✅ Notifications (push updates) ✅ Multiplayer games ✅ Live trading/stocks ✅ Collaborative editing ✅ Live sports scores
❌ Не используй для обычного API (используй REST) ❌ Не используй для больших файлов (используй HTTP)
Преимущества
✅ Low latency (низкая задержка) ✅ Efficient (один TCP connection) ✅ Real-time (двусторонняя коммуникация) ✅ Lower server load
Недостатки
❌ Proxies не всегда поддерживают ❌ Сложнее масштабировать (sticky sessions) ❌ Требует постоянное соединение
Ключевые правила
✅ Используй URLSessionWebSocketTask (встроенный iOS 13+) ✅ Обрабатывай ошибки соединения ✅ Реализуй ping-pong для keep-alive ✅ Отправляй heartbeat периодически ✅ Переподключайся при разрыве ❌ Не отправляй большие сообщения ❌ Не забывай закрывать соединение
WebSocket — мощный инструмент для real-time коммуникации. Правильное использование обеспечивает отзывчивое и efficient приложение.