引言:为什么 WebSocket 对 Swift 开发者很重要
在现代移动和桌面开发中,用户已经习惯了即时更新:新闻推送无需重新加载即可更新,聊天中对话者的状态实时变化,股票报价以毫秒级延迟到达。传统的 HTTP 及其请求-响应模型对于此类任务效率低下——它会给服务器和设备电池造成过大的负载。
WebSocket 协议应运而生。它在客户端(Swift 中的 iOS/macOS 应用)和服务器之间建立了一个永久的双向连接。在本文中,我们将介绍在 Swift 中使用 WebSocket 的两种主要方式:原生 URLSessionWebSocketTask(iOS 13+ / macOS 10.15+)和流行的第三方库 Starscream。您将学习如何创建实时聊天、配置自动重连以及处理错误。
Swift 中的 WebSocket 基础:URLSessionWebSocketTask
从 iOS 13 和 macOS Catalina 开始,Apple 通过 URLSessionWebSocketTask 类提供内置的 WebSocket 支持。这是一种简单且安全的方式,无需安装额外的依赖项。
创建和配置连接
首先,让我们创建一个 URLSession 实例并设置配置。注意:要使用 WebSocket,需要使用 wss:// 协议(安全连接)或 ws://(非安全连接,仅用于开发)。
import Foundation
class WebSocketManager: NSObject { private var webSocketTask: URLSessionWebSocketTask? private let session: URLSession override init() { let config = URLSessionConfiguration.default config.timeoutIntervalForRequest = 30 config.waitsForConnectivity = true self.session = URLSession(configuration: config, delegate: nil, delegateQueue: OperationQueue()) super.init() } func connect() { guard let url = URL(string: "wss://echo.websocket.org") else { return } webSocketTask = session.webSocketTask(with: url) webSocketTask?.resume() print("WebSocket connection established") receiveMessage() }}发送和接收消息
WebSocket 支持两种类型的消息:字符串和二进制(Data)。让我们来看一下发送:
func sendMessage(_ text: String) { let message = URLSessionWebSocketTask.Message.string(text) webSocketTask?.send(message) { error in if let error = error { print("Send error: \\(error.localizedDescription)") } else { print("Message sent: \\(text)") } }}要接收消息,需要实现 receive 方法的递归调用:
private func receiveMessage() { webSocketTask?.receive { [weak self] result in switch result { case .success(let message): switch message { case .string(let text): print("Received text message: \\(text)") case .data(let data): print("Received binary data: \\(data.count) bytes") @unknown default: break } // Continue listening for the next messages self?.receiveMessage() case .failure(let error): print("Receive error: \\(error.localizedDescription)") // Here you can implement reconnection } }}关闭连接与错误处理
正确终止 WebSocket 连接是生产应用中的一个重要部分:
func disconnect() { let closeCode = URLSessionWebSocketTask.CloseCode.normalClosure webSocketTask?.cancel(with: closeCode, reason: nil) p