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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:45:05