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

连接MQTT Broker时遇CocoaMQTT错误:deliver delegate为nil,帧被丢弃

解决CocoaMQTT错误:The deliver delegate is nil!!!

以下是针对问题的具体修复步骤:

1. 修复MQTTManager实例被提前释放的问题

你在sendTelemetryMsg中创建的MQTTManager是局部变量,函数执行完毕后会被ARC自动回收,导致CocoaMQTT的代理对象消失,触发deliver delegate is nil错误。需要将MQTTManager声明为类属性,避免提前释放:

class YourClass: NSObject {
    private var mqttManager: MQTTManager? // 声明为类属性,延长生命周期

    @objc(sendTelemetryMsg:withUrl:withResolver:withRejecter:)
    func sendTelemetryMsg(password: String, url: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
        mqttManager = MQTTManager()
        // 后续操作移至连接成功回调中
    }
}

2. 修正CocoaMQTT初始化的参数错误

你的connectMQTT方法中,clientID和host参数完全写反了,还多了一个多余的双引号,这会导致连接到错误的Broker地址:

func connectMQTT() {
    // 正确参数顺序:clientID是自定义客户端标识,host是Broker地址
    mqtt = CocoaMQTT(clientID: "your-client-id-435345", host: "broker.hivemq.com", port: 1883)
    mqtt.delegate = self
    mqtt.connect()
}

3. 延迟订阅、发布操作到连接成功后

MQTT连接是异步操作,不能在调用connect()后立即执行订阅和发布,必须等待didConnectAck回调确认连接成功后再执行:

第一步:在MQTTManager中添加连接成功回调

class MQTTManager: CocoaMQTTDelegate {
    var mqtt: CocoaMQTT!
    var onConnected: (() -> Void)? // 新增连接成功回调闭包

    // ... 其他代理方法保持不变

    func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
        if ack == .accept {
            print("Connected to the MQTT!")
            onConnected?() // 触发连接成功回调
        } else {
            print("Failed to connect to MQTT, ack code: \(ack.rawValue)")
        }
    }
}

第二步:在调用方法中绑定回调执行操作

@objc(sendTelemetryMsg:withUrl:withResolver:withRejecter:)
func sendTelemetryMsg(password: String, url: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
    mqttManager = MQTTManager()
    mqttManager?.onConnected = { [weak self] in
        guard let self = self else {
            reject("ERROR", "Manager deallocated", nil)
            return
        }
        let topic = "your-topic"
        self.mqttManager?.subscribeToTopic(topic: topic)
        let message = "Hello, IoT Device!"
        self.mqttManager?.publishData(topic: topic, message: message)
        resolve("Message published successfully")
    }
    // 处理连接失败场景
    mqttManager?.mqttDidDisconnect = { _, err in
        if let err = err {
            reject("CONNECT_FAILED", err.localizedDescription, err)
        }
    }
    mqttManager?.connectMQTT()
}

完整修正后的MQTTManager代码

import Foundation
import CocoaMQTT

class MQTTManager: CocoaMQTTDelegate {
    var mqtt: CocoaMQTT!
    var onConnected: (() -> Void)?
    var mqttDidDisconnect: ((CocoaMQTT, Error?) -> Void)?

    func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
        print("Published message with ID: \(id)")
    }
    
    func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
        print("Subscribed to topics: \(success)")
    }
    
    func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
        print("Unsubscribed from topics: \(topics)")
    }
    
    func mqttDidPing(_ mqtt: CocoaMQTT) {
        print("Pinged!")
    }
    
    func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
        print("Ponged!")
    }
    
    func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: (any Error)?) {
        print("Disconnected from the MQTT: \(err?.localizedDescription ?? "No error")")
        mqttDidDisconnect?(mqtt, err)
    }

    func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
        if ack == .accept {
            print("Connected to the MQTT!")
            onConnected?()
        } else {
            print("Failed to connect to MQTT, ack code: \(ack.rawValue)")
        }
    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
        print("Data published successfully")
    }

    func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
        if let messageString = message.string {
            print("Received message on topic \(message.topic): \(messageString)")
        }
    }

    func connectMQTT() {
        mqtt = CocoaMQTT(clientID: "your-client-id-435345", host: "broker.hivemq.com", port: 1883)
        mqtt.delegate = self
        mqtt.connect()
    }
    
    func subscribeToTopic(topic: String) {
        mqtt.subscribe(topic)
    }
    
    func publishData(topic: String, message: String) {
        mqtt.publish(topic, withString: message, qos: .qos1)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:10:55