Swift使用CocoaMQTT通过WebSocket连接MQTT回调未触发如何解决
问题修复方案
核心问题说明
代码最关键的问题是没有给CocoaMQTT实例绑定delegate,所以所有代理回调都不会触发。除此之外还有几个影响连接和排查的小问题:
- 在调用
connect()之后才设置logLevel,会丢失连接初始化阶段的日志,无法及时定位连接错误 - 忽略了
connect()方法的返回值,无法判断连接请求是否成功发起 - 未做ATS配置,iOS系统会默认拦截不符合安全要求的wss连接,哪怕开启了允许不信任证书的配置也会被拦截
修复后的代码
import CocoaMQTT class MqttSocketManager: NSObject, CocoaMQTTDelegate { static let shared = MqttSocketManager() var mqtt: CocoaMQTT! func start() { let websocket = CocoaMQTTWebSocket(uri: "/mqtt") let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier) mqtt = CocoaMQTT(clientID: clientID, host: "cpl-emqx-socket.staging-bitcastle.work", port: 8083, socket: websocket) // 核心修复:设置代理 mqtt.delegate = self mqtt.keepAlive = 60 mqtt.enableSSL = true mqtt.allowUntrustCACertificate = true // 提前设置日志等级,方便排查连接问题 mqtt.logLevel = .debug // 判断连接请求是否成功发起 let connectRequestSuccess = mqtt.connect() print("连接请求发起结果:\(connectRequestSuccess)") } func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) { if ack == .accept { mqtt.subscribe("orderbook_BTC_USDT") } print("Mqtt: DidConnect, ack状态码:\(ack.rawValue)") } func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) { print("Mqtt: didPublishMessage") } func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) { print("Mqtt: didPublishAck") } func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) { print("Mqtt: didReceiveMessage, 消息内容:\(message.string ?? "空内容")") } func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) { print("Mqtt: didSubscribeTopics, 成功:\(success), 失败:\(failed)") } func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) { print("Mqtt: didUnsubscribeTopics") } func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) { print("Mqtt: mqttDidDisconnect, 错误信息:\(err?.localizedDescription ?? "无错误")") } func mqttDidPing(_ mqtt: CocoaMQTT) { print("Mqtt: mqttDidPing") } func mqttDidReceivePong(_ mqtt: CocoaMQTT) { print("Mqtt: mqttDidReceivePong") } }
额外必要配置
需要在项目的Info.plist中添加如下ATS配置,允许访问测试环境的服务:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <false/> <key>NSExceptionDomains</key> <dict> <key>staging-bitcastle.work</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <false/> </dict> </dict> </dict>
后续排查建议
如果修复后还是无法连接,直接查看Xcode控制台的debug日志,CocoaMQTT输出的日志会明确标注是域名解析失败、证书验证失败还是服务端主动拒绝连接。
内容的提问来源于stack exchange,提问作者Bad_Developer
相关产品推荐
相关产品推荐

