You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS本地Socket通信:如何禁用Swift原生WebSocket的握手流程?

解决iOS原生WebSocket跳过握手的问题

你找的nw_ws_options_set_skip_handshake确实是关键,但它属于Apple底层的Network框架,而你当前用的URLSessionWebSocketTask是上层封装的API,强制遵循标准WebSocket协议的握手流程,并没有开放跳过握手的配置选项。所以要实现跳过握手的需求,你需要直接基于Network框架来构建WebSocket连接,而不是用URLSession的封装。

具体实现步骤

  1. 导入Network框架(iOS 13.0+支持)
  2. 创建WebSocket选项并开启跳过握手配置
  3. 构建NWParameters并关联WebSocket协议
  4. 创建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é

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:12:34