如何为URLSessionWebSocketTask添加请求头?及事件订阅指导
URLSessionWebSocketTask 请求头与事件订阅问题解答
一、通过URLRequest设置WSS请求头是否合规?
完全合规。WebSocket(包括WSS)的握手阶段基于HTTP/HTTPS协议,客户端会发送HTTP请求触发协议升级,你通过URLRequest设置的请求头会在握手阶段发送到服务器,完全符合WebSocket协议规范。当前代码写法没问题,自定义头(login、passcode等)会正常传递给服务端校验。
二、如何订阅WebSocket相关事件?
结合URLSessionWebSocketDelegate代理方法+主动接收消息逻辑即可实现,具体方案如下:
1. 实现核心代理方法
确保你的类遵守URLSessionDelegate和URLSessionWebSocketDelegate协议,实现关键事件回调:
extension YourClassName: URLSessionDelegate, URLSessionWebSocketDelegate { // 连接成功建立时触发 func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) { print("WebSocket连接已打开") // 连接成功后启动消息接收 startReceivingMessages() } // 连接关闭时触发 func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) { let reasonStr = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "无" print("WebSocket连接关闭,code: \(closeCode.rawValue),原因: \(reasonStr)") } // 任务出错时触发 func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { print("WebSocket任务出错: \(error.localizedDescription)") } } }
2. 消息接收逻辑
有两种实现方式,按需选择:
方式一:传统回调循环(兼容iOS 13及以下)
private func startReceivingMessages() { webSocketTask.receive { [weak self] result in guard let self = self else { return } switch result { case .success(let message): // 处理不同类型的消息 switch message { case .string(let str): print("收到字符串消息: \(str)") case .data(let data): print("收到二进制消息: \(data)") @unknown default: print("收到未知类型消息") } // 循环调用,持续接收下一条消息 self.startReceivingMessages() case .failure(let error): print("接收消息失败: \(error.localizedDescription)") } } }
方式二:异步序列(iOS 15+ 推荐)
利用messages异步序列简化代码:
private func startReceivingMessages() { Task { for await message in webSocketTask.messages { switch message { case .string(let str): print("收到字符串消息: \(str)") case .data(let data): print("收到二进制消息: \(data)") @unknown default: print("收到未知类型消息") } } } }
3. 启动WebSocket任务
初始化后记得启动任务,否则不会触发连接:
public override init() { super.init() webSocketTask = urlSession.webSocketTask(with: urlRequest) webSocketTask.resume() }
内容的提问来源于stack exchange,提问作者ex4mpl3
相关产品推荐
相关产品推荐

