Swift调用sendMessage时WebSocket服务器收不到数据无报错求助
问题排查与修复方案
1. URLSession实例被局部创建导致提前释放
在connectToServer(_:)方法中,urlSession是DispatchQueue.main.async闭包内的局部变量,闭包执行完毕后会被ARC自动释放。而socket依赖该URLSession实例存在,后续调用sendMessage(_:)时,socket已失去有效会话上下文,无法正常发送消息。
修复方法:将urlSession改为类属性,确保其生命周期与NetworkKit实例一致:
class NetworkKit: NSObject, ObservableObject, URLSessionWebSocketDelegate { private var socket: URLSessionWebSocketTask? = nil private var socketHasBeenEstablished = false private let logger = Logger(label: "websocket") private let operationQueue = OperationQueue() private var urlSession: URLSession? // 新增类属性存储URLSession func connectToServer(_ address: String) throws { logger.info("Connecting to \(address)") if let url = URL(string: address) { DispatchQueue.main.async { let urlRequest = URLRequest(url: url) self.urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: self.operationQueue) self.socket = self.urlSession?.webSocketTask(with: urlRequest) self.socket?.maximumMessageSize = 10_000_0000 self.socket?.resume() self.socket?.send(URLSessionWebSocketTask.Message.string("sup world!"), completionHandler: { error in if let error = error { self.logger.error(Logger.Message(stringLiteral: error.localizedDescription)) } }) } } else { throw ConnectionEstablishmentFailedError.InvalidAddress } } // 通过Delegate方法确认连接成功 func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) { socketHasBeenEstablished = true logger.info("Connection succeeded: \(socketHasBeenEstablished)") } func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) { socketHasBeenEstablished = false logger.info("Connection closed") } }
2. sendMessage方法中completionHandler逻辑反转
当前代码中,completionHandler在error为nil(发送成功)时输出"Unknown error",逻辑完全颠倒,会误导排查方向。
修复方法:修正逻辑并增加连接状态校验:
func sendMessage(_ data: String) throws { guard socketHasBeenEstablished else { throw ConnectionEstablishmentFailedError.NotConnected // 自定义未连接错误 } logger.info("Sending data: \(data) to websocket server.") let message = URLSessionWebSocketTask.Message.string(data) DispatchQueue.main.async { self.socket?.send(message, completionHandler: { error in if let error = error { self.logger.error(Logger.Message(stringLiteral: error.localizedDescription)) } else { self.logger.info("Message sent successfully") } }) } }
3. 错误的连接状态标记逻辑
原代码在调用socket?.resume()后立即标记连接成功,但resume()仅启动任务,此时连接未完成握手,后续发送消息可能因连接未就绪失败。
修复方法:通过URLSessionWebSocketDelegate的didOpenWithProtocol方法确认连接成功后,再标记socketHasBeenEstablished为true,同时在sendMessage(_:)中先校验连接状态。
4. sendMessage中重复调用resume()
WebSocketTask首次resume()后即处于活跃状态,重复调用会导致任务状态异常,影响消息发送。
修复方法:删除sendMessage(_:)中的socket?.resume()行。
内容的提问来源于stack exchange,提问作者Praanto
相关产品推荐
相关产品推荐

