iOS本地Socket通信:如何禁用Swift原生WebSocket的握手流程?
解决iOS原生WebSocket跳过握手的问题
你找的nw_ws_options_set_skip_handshake确实是关键,但它属于Apple底层的Network框架,而你当前用的URLSessionWebSocketTask是上层封装的API,强制遵循标准WebSocket协议的握手流程,并没有开放跳过握手的配置选项。所以要实现跳过握手的需求,你需要直接基于Network框架来构建WebSocket连接,而不是用URLSession的封装。
具体实现步骤
- 导入Network框架(iOS 13.0+支持)
- 创建WebSocket选项并开启跳过握手配置
- 构建NWParameters并关联WebSocket协议
- 创建NWWebSocket连接并实现代理处理收发逻辑
完整代码示例
import Network class WebSocketManager: NSObject { private var webSocket: NWWebSocket? func connectToServer() { // 配置WebSocket选项:跳过握手 let wsOptions = NWProtocolWebSocket.Options() wsOptions.skipHandshake = true // 这等价于你找到的nw_ws_options_set_skip_handshake // 构建TCP参数并绑定WebSocket协议 let tcpParameters = NWParameters.tcp tcpParameters.defaultProtocolStack.applicationProtocols.insert(wsOptions, at: 0) // 创建服务器端点 guard let url = URL(string: "ws://192.168.43.1:6000"), let host = NWEndpoint.Host(url.host!), let port = NWEndpoint.Port(rawValue: UInt16(url.port!)) else { print("无效的服务器地址") return } let serverEndpoint = NWEndpoint.hostPort(host: host, port: port) // 创建WebSocket连接并设置代理 webSocket = NWWebSocket(endpoint: serverEndpoint, parameters: tcpParameters) webSocket?.delegate = self // 启动连接,指定处理队列 webSocket?.start(queue: DispatchQueue.global()) } func sendMessage(_ content: String) { webSocket?.send(.string(content)) { error in if let error = error { print("发送消息失败: \(error.localizedDescription)") } } } } // 实现NWWebSocket代理方法,处理连接、收发、断开事件 extension WebSocketManager: NWWebSocketDelegate { func webSocketDidConnect(_ webSocket: NWWebSocket) { print("WebSocket连接成功!") // 连接成功后开始循环发送消息(注意弱引用避免内存泄漏) DispatchQueue.global().asyncAfter(deadline: .now() + 1) { [weak self] in self?.sendMessage("New Message") // 递归实现循环发送,间隔1秒 DispatchQueue.global().asyncAfter(deadline: .now() + 1) { self?.sendMessage("New Message") } } } func webSocketDidDisconnect(_ webSocket: NWWebSocket, closeCode: NWProtocolWebSocket.CloseCode, reason: Data?) { print("WebSocket断开连接,错误码: \(closeCode.rawValue)") } func webSocket(_ webSocket: NWWebSocket, didReceiveMessage message: NWProtocolWebSocket.Message) { switch message { case .string(let text): print("收到文本消息: \(text)") case .data(let data): print("收到二进制数据: \(data)") default: print("收到未知类型消息") } } func webSocket(_ webSocket: NWWebSocket, didReceiveError error: Error) { print("WebSocket发生错误: \(error.localizedDescription)") } }
使用方式
// 在需要的地方初始化并连接 let wsManager = WebSocketManager() wsManager.connectToServer()
注意事项
- 确保你的App部署目标是iOS 13.0或以上,因为NWWebSocket是iOS13才引入的API
- 服务器端必须配合跳过握手流程,直接和客户端交换WebSocket帧(不需要处理HTTP握手请求)
- 循环发送消息时要使用弱引用
[weak self],避免循环引用导致内存泄漏
内容的提问来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

