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

Swift SocketIO客户端无法连接:模拟器环境下的问题求助

问题

通过Swift Package Manager安装swift-socketio-client后,使用以下代码尝试建立Socket连接(测试环境为模拟器):

let manager = SocketManager(socketURL: URL(string: "http://127.0.0.1:3000")!, config: [.log(true)])
let defaultNamespaceSocket = manager.defaultSocket
let socket = manager.socket(forNamespace: "/message")

socket.on(clientEvent: .connect) {data, ack in
    print("socket connected")
}

socket.connect()

API未记录新连接,connect回调也未执行。Postman验证URL有效,日志信息如下:

LOG SocketIOClient{/message}: Adding handler for event: connect
LOG SocketIOClient{/message}: Handling event: statusChange with data: [connecting, 2]
LOG SocketIOClient{/message}: Joining namespace /message
LOG SocketManager: Tried connecting socket when engine isn't open. Connecting
LOG SocketManager: Adding engine
LOG SocketManager: Manager is being released
LOG SocketIOClient{/message}: Client is being released
LOG SocketEngine: Starting engine. Server: http://127.0.0.1:3000
LOG SocketEngine: Handshaking
LOG SocketIOClient{/}: Client is being released
LOG SocketEnginePolling: Doing polling GET http://127.0.0.1:3000/socket.io/?transport=polling&b64=1&EIO=4
LOG SocketEnginePolling: Got polling response
LOG SocketEnginePolling: Got poll message: 0{"sid":"tLgrfJ8T1cQKPms8AAAJ","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000,"maxPayload":100000000}
LOG SocketEngine: Got message: 0{"sid":"tLgrfJ8T1cQKPms8AAAJ","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000,"maxPayload":100000000}
LOG SocketEngine: Engine is being released
nw_connection_copy_connected_local_endpoint_block_invoke [C2] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection
nw_connection_copy_connected_remote_endpoint_block_invoke [C2] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection

故障原因及解决方案

  • 核心原因:Socket对象被提前释放
    从日志里的SocketManager: Manager is being released和SocketIOClient{/message}: Client is being released可以明确看出,manager和socket都是局部变量,代码执行完当前作用域后,ARC会立即回收这些对象,导致连接流程中途中断,自然无法触发connect回调。

  • 解决方案:将Socket对象声明为类属性或全局变量
    把manager和socket提升到类的实例属性(比如ViewController的属性),或者声明为全局变量,确保它们在连接的整个生命周期内保持引用,不会被提前回收。修改示例如下:

    class ViewController: UIViewController {
        // 声明为类属性,保持引用
        private let socketManager = SocketManager(socketURL: URL(string: "http://127.0.0.1:3000")!, config: [.log(true)])
        private var messageSocket: SocketIOClient!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            messageSocket = socketManager.socket(forNamespace: "/message")
            
            messageSocket.on(clientEvent: .connect) { data, ack in
                print("socket connected")
            }
            
            messageSocket.connect()
        }
    }
    
  • 额外检查点
    确认服务器端已正确配置/message命名空间,允许客户端接入;同时确保模拟器和服务器在同一网络环境(本地127.0.0.1是没问题的,因为模拟器共享主机网络)。

内容的提问来源于stack exchange,提问作者Alms

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:20:20