1. WebSocket 基础
1.1 什么是 WebSocket?
- 全双工通信协议:基于 TCP,允许客户端与服务器建立持久连接,双方可主动发送数据。
- 实时性:替代 HTTP 轮询,适用于实时聊天、股票行情、在线游戏等场景。
- 协议升级:通过 HTTP 握手(
Upgrade: websocket
)建立连接,后续通过 WebSocket 帧通信。
1.2 与 HTTP 对比
特性 | HTTP | WebSocket |
---|
连接方式 | 短连接(请求-响应后断开) | 长连接(持久化,双向通信) |
通信方向 | 单向(客户端主动请求) | 双向(客户端/服务器均可主动发送) |
头部开销 | 每次请求携带完整 HTTP 头 | 初始握手后,数据帧头部极小 |
适用场景 | 静态资源获取、REST API | 实时数据传输(如聊天、推送) |
2. iOS 中 WebSocket 的实现方式
2.1 官方方案:URLSessionWebSocketTask
(iOS 13+)
- 核心类:
URLSessionWebSocketTask
(属于 URLSession
框架)
- 特点:
- 原生支持,无需第三方库。
- 支持 iOS 13+,兼容性有限。
- 提供基本连接管理、消息发送/接收功能。
基本使用流程:
import Foundation
actor WebSocketManager {
private let session = URLSession(configuration: .default)
private var webSocketTask: URLSessionWebSocketTask?
func connect() {
guard let url = URL(string: "wss://your-server.com/socket") else {
print("无效的 URL")
return
}
webSocketTask = session.webSocketTask(with: url)
webSocketTask?.resume()
receiveMessage()
}
private func receiveMessage() {
webSocketTask?.receive { [weak self] result in
Task {
await self?.handleReceive(result)
}
}
}
private func handleReceive(_ result: Result<URLSessionWebSocketTask.Message, Error>) {
switch result {
case .success(let message):
switch message {
case .data(let data):
print("收到二进制数据: (data)")
case .string(let text):
print("收到文本消息: (text)")
@unknown default:
fatalError()
}
self.receiveMessage()
case .failure(let error):
print("接收失败: (error)")
}
}
func sendMessage(_ message: String) {
webSocketTask?.send(.string(message)) { error in
if let error = error {
print("发送失败: (error)")
} else {
print("消息发送成功")
}
}
}
func disconnect() {
webSocketTask?.cancel(with: .goingAway, reason: nil)
print("连接已关闭")
}
}
2.2 第三方库:Starscream
- 适用场景:支持 iOS 11+,功能更丰富(如 SSL 验证、自定义头、自动重连)。
- 集成方式:通过 CocoaPods 或 SPM 安装。
基本使用:
import Starscream
var request = URLRequest(url: URL(string: "wss://your-server.com/socket")!)
request.setValue("Bearer token", forHTTPHeaderField: "Authorization")
let socket = WebSocket(request: request)
socket.delegate = self
socket.connect()
socket.write(string: "Hello Server")
socket.disconnect()
extension ViewController: WebSocketDelegate {
func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .connected(let headers):
print("连接成功: \(headers)")
case .disconnected(let reason, let code):
print("断开连接: \(reason), code: \(code)")
case .text(let text):
print("收到文本: \(text)")
case .binary(let data):
print("收到二进制数据: \(data)")
case .error(let error):
print("错误: \(error?.localizedDescription ?? "")")
case .cancelled:
print("连接取消")
default:
break
}
}
}
3. 核心功能与最佳实践
3.1 连接管理
3.2 消息处理
3.3 线程安全
3.4 错误处理与断线重连
- 监听错误事件:捕获连接错误、消息发送失败等。
- 重连策略:指数退避重试(如 1s、2s、4s...)。
4. 安全性
- 使用
wss://
:WebSocket Secure(基于 TLS 加密)。
- 证书验证:在
URLSessionDelegate
中处理 SSL 证书校验(如需自定义)。
- 身份验证:通过 HTTP 头(如
Authorization: Bearer token
)或握手阶段传递 Token。
5. 性能优化
- 消息压缩:服务器启用 WebSocket 扩展(如 permessage-deflate)。
- 连接复用:避免频繁创建/销毁连接。
- 数据量控制:避免单次发送过大消息(分片传输)。
6. 常见问题与解决方案
问题 | 解决方案 |
---|
连接不稳定 | 实现自动重连逻辑,监听网络状态变化(如 Network.framework )。 |
内存泄漏 | 使用 [weak self] 避免循环引用,及时释放不再使用的 WebSocket 实例。 |
后台连接断开 | 启用后台模式(需配置 Capabilities > Background Modes > Remote notifications )。 |
消息顺序混乱 | 在消息中添加序列号,客户端按序处理。 |
7. 适用场景示例
- 实时聊天应用:消息即时推送、已读回执。
- 金融行情推送:实时股票价格、K线数据。
- 多人在线游戏:玩家位置同步、状态更新。
- 物联网控制:设备状态监控、指令下发。
总结
- 核心价值:WebSocket 为 iOS 应用提供高效、实时的双向通信能力。
- 选择方案:优先使用
URLSessionWebSocketTask
(iOS 13+),低版本或需高级功能时选择 Starscream。
- 关键实践:心跳保活、错误重连、数据序列化、线程安全。