emqx / CocoaMQTT

MQTT 5.0 client library for iOS and macOS written in Swift
https://www.emqx.com/en
Other
1.6k stars 422 forks source link

having error CocoaMQTTCONNACKReasonCode(rawValue: -121) #520

Closed RehanHussain07 closed 1 year ago

RehanHussain07 commented 1 year ago

I am having a disconnection error right after showing connecting state in logs..

new state: connecting [TRACE] [didReceive]: trust: <SecTrustRef: 0x600000904140> [TRACE] [didConnectAck]: ack: CocoaMQTTCONNACKReasonCode(rawValue: -121) [TRACE] [withError]: Error Domain=MGCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo={NSLocalizedDescription=Socket closed by remote peer} [TRACE] [didStateChangeTo]: new state: disconnected [TRACE] [didStateChangeTo]: new state: disconnected

leeway1208 commented 1 year ago

It seems the server closed this connection!

Could you please provide more details for analyzing this error? (i.e: More clearly code etc.)

RehanHussain07 commented 1 year ago

Hello,

I have used your example code but tried to change with my p.12 certificate and port and urls and enclosing my sample please help. Regards, Rehan Hussain

On Sun, Apr 2, 2023 at 3:33 PM leeway @.***> wrote:

It seems the server closed this connection!

Could you please provide more details for analyzing this error? (i.e: More clearly code etc.)

— Reply to this email directly, view it on GitHub https://github.com/emqx/CocoaMQTT/issues/520#issuecomment-1493285563, or unsubscribe https://github.com/notifications/unsubscribe-auth/A6HBBRZTO4ZG4I67JYMFWKTW7FFHTANCNFSM6AAAAAAWKCTB3E . You are receiving this because you authored the thread.Message ID: @.***>

RehanHussain07 commented 1 year ago

Its your viewcontroller from example

//

// ViewController.swift

// Example

//

// Created by CrazyWisdom on 15/12/14.

// Copyright © 2015年 emqtt.io. All rights reserved.

//

import Foundation

import UIKit

import CocoaMQTT

import MqttCocoaAsyncSocket

import CommonCrypto

import IBMMobileFoundationSwift

import CocoaAsyncSocket

class ViewController: UIViewController {

//let defaultHost = "localhost"

//OR

//TEST Broker

*let* defaultHost =

"79d9341c2973443a8e3a2e0e7ef2e9d7.s2.eu.hivemq.cloud" //" a5x3yf174qsgz-ats.iot.ap-south-1.amazonaws.com" //"broker-cn.emqx.io"

*var* mqtt5: CocoaMQTT5?

*var* mqtt: CocoaMQTT?

*var* animal: String?

*var* mqttVesion: String?

***@***.**** *weak* *var* versionControl: UISegmentedControl!

***@***.**** *weak* *var* connectButton: UIButton!

***@***.**** *weak* *var* animalsImageView: UIImageView! {

    *didSet* {

        animalsImageView.clipsToBounds = *true*

        animalsImageView.layer.borderWidth = 1.0

        animalsImageView.layer.cornerRadius = animalsImageView.frame.

width / 2.0

    }

}

***@***.**** *func* connectToServer() {

    *if* mqttVesion == "3.1.1" {

        _ = mqtt!.connect()

    }*else* *if* mqttVesion == "5.0"{

        _ = mqtt5!.connect()

    }

}

***@***.**** *func* mqttVersionControl(_ sender: UISegmentedControl) {

    animal = tabBarController?.selectedViewController?.tabBarItem.title

    mqttVesion = versionControl.titleForSegment(at: versionControl.

selectedSegmentIndex)

    mqttSettingList()

    print("welcome to MQTT \(String(describing: mqttVesion))  \(String(

describing: animal))")

}

*func* sendAuthToServer(){

    *let* authProperties = MqttAuthProperties()

    mqtt5!.auth(reasonCode:

CocoaMQTTAUTHReasonCode.continueAuthentication, authProperties: authProperties)

}

*override* *func* viewDidLoad() {

    *super*.viewDidLoad()

    //checkJwt()

    navigationController?.interactivePopGestureRecognizer?.isEnabled =

false

    tabBarController?.delegate = *self*

    animal = tabBarController?.selectedViewController?.tabBarItem.title

    mqttVesion = versionControl.titleForSegment(at: versionControl.

selectedSegmentIndex)

    mqttSettingList()

    print("welcome to MQTT \(String(describing: mqttVesion))  \(String(

describing: animal))")

}

*override* *func* viewWillAppear(_ animated: Bool) {

    navigationController?.navigationBar.isHidden = *false*

    getCertificate()

}

*func* certificateFromCertificate(certP12: String, psswd: String) ->

SecCertificate? {

    *guard* *let* pkcs12Data = Data.init(base64Encoded: certP12) *else*

{

        *return* *nil*

    }

    *var* importResult: CFArray? = *nil*

    *let* err = SecPKCS12Import(

        pkcs12Data *as* NSData,

        [kSecImportExportPassphrase *as* String: psswd] *as*

NSDictionary,

        &importResult

    )

    *guard* err == errSecSuccess *else* {

        *return* *nil*

    }

    *let* importItems = importResult! *as*! [[String:*Any*]]

    *guard* *let* importDict = importItems.first *else* {

        *return* *nil*

    }

    *let* identity = importDict[kSecImportItemIdentity *as* String]!

as! SecIdentity

    *var* certificate: SecCertificate? = *nil*

    *let* err2 = SecIdentityCopyCertificate(identity, &certificate)

    *guard* err2 == errSecSuccess *else* {

        *return* *nil*

    }

    *return* certificate!

}

*func* mqttSettingList(){

    //mqttSetting()

    selfSignedSSLSetting()

   // simpleSSLSetting()

    //mqttWebsocketsSetting()

    //mqttWebsocketSSLSetting()

}

*func* mqttSetting() {

    *if* mqttVesion == "3.1.1" {

        *let* clientID = "CocoaMQTT-\(animal!)-" + String(ProcessInfo().

processIdentifier)

        mqtt = CocoaMQTT(clientID: clientID, host: "broker-cn.emqx.io",

port: 1883)

        mqtt!.logLevel = .debug

        mqtt!.username = ""

        mqtt!.password = ""

        mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string: "")

        mqtt!.keepAlive = 60

        mqtt!.delegate = *self*

        //mqtt!.autoReconnect = true

    }*else* *if* mqttVesion == "5.0" {

        *let* clientID = "992F5522-7A34-4176-94D2-78D5C16B3222"

        mqtt5 = CocoaMQTT5(clientID: clientID, host: defaultHost, port:

8883/1883/)

        mqtt5!.logLevel = .debug

        *let* connectProperties = MqttConnectProperties()

        connectProperties.topicAliasMaximum = 0

        connectProperties.sessionExpiryInterval = 0

        connectProperties.receiveMaximum = 100

        connectProperties.maximumPacketSize = 500

        mqtt5!.connectProperties = connectProperties

        mqtt!.allowUntrustCACertificate = *true*

        mqtt5!.username = ""

        mqtt5!.password = ""

        *let* lastWillMessage = CocoaMQTT5Message(topic: "/will",

string: "dieout")

        lastWillMessage.contentType = "JSON"

        lastWillMessage.willResponseTopic = "/will"

        lastWillMessage.willExpiryInterval = .max

        lastWillMessage.willDelayInterval = 0

        lastWillMessage.qos = .qos1

        //mqtt5!.willMessage = lastWillMessage

        mqtt5!.keepAlive = 60

        mqtt5!.delegate = *self*

        //mqtt5!.autoReconnect = true

    }

}

*func* simpleSSLSetting() {

    *if* mqttVesion == "3.1.1" {

        *let* clientID = "CocoaMQTT-\(animal!)-" + String(ProcessInfo().

processIdentifier)

        mqtt = CocoaMQTT(clientID: clientID, host: defaultHost, port:

8883)

        mqtt!.username = "rehan"

        mqtt!.password = "hussain007"

        mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string:

"dieout")

        mqtt!.keepAlive = 60

        mqtt!.delegate = *self*

        mqtt!.enableSSL = *true*

    }*else* *if* mqttVesion == "5.0" {

        *let* clientID = "992F5522-7A34-4176-94D2-78D5C16B3222"

        mqtt5 = CocoaMQTT5(clientID: clientID, host: defaultHost, port:

8883)

        mqtt5?.logLevel = .debug

        *let* connectProperties = MqttConnectProperties()

        connectProperties.topicAliasMaximum = 0

        connectProperties.sessionExpiryInterval = 0

        connectProperties.receiveMaximum = 100

        connectProperties.maximumPacketSize = 500

        mqtt5!.connectProperties = connectProperties

        mqtt!.allowUntrustCACertificate = *true*

        mqtt5!.username = ""

        mqtt5!.password = ""

        mqtt5!.willMessage = CocoaMQTT5Message(topic:

"delhivery/mts/v3/location-data/preprod", string: "")

        mqtt5!.keepAlive = 60

        mqtt5!.delegate = *self*

// mqtt5!.sslSettings = [

// GCDAsyncSocketManuallyEvaluateTrust: NSNumber(booleanLiteral: true),

// GCDAsyncSocketUseCFStreamForTLS: NSNumber(booleanLiteral: false),

// kCFStreamSSLPeerName as String: "" as NSString,

// GCDAsyncSocketSSLProtocolVersionMin: NSNumber(integerLiteral: Int(SSLProtocol.tlsProtocol1.rawValue)),

// GCDAsyncSocketSSLProtocolVersionMax: NSNumber(integerLiteral: Int(SSLProtocol.tlsProtocol12.rawValue)),

// ]

        //mqtt5!.enableSSL = true

    }

}

*func* selfSignedSSLSetting() {

    *if* mqttVesion == "3.1.1" {

        *let* clientID = "CocoaMQTT-\(animal!)-" + String(ProcessInfo().

processIdentifier)

        mqtt = CocoaMQTT(clientID: clientID, host: defaultHost, port:

8883)

        mqtt!.username = ""

        mqtt!.password = ""

        mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string:

"dieout")

        mqtt!.keepAlive = 60

        mqtt!.delegate = *self*

        mqtt!.enableSSL = *true*

        mqtt!.allowUntrustCACertificate = *true*

        *let* clientCertArray = getClientCertFromP12File(certName:

"client", certPassword: @.***")

        *var* sslSettings: [String: NSObject] = [:]

        sslSettings[kCFStreamSSLCertificates *as* String] =

clientCertArray

        mqtt!.sslSettings = sslSettings

    }*else* *if* mqttVesion == "5.0" {

        *let* clientID = "CocoaMQTT5-\(animal!)-" + String(ProcessInfo

().processIdentifier)

        mqtt5 = CocoaMQTT5(clientID: clientID, host: defaultHost, port:

UInt16(8883))

        *let* connectProperties = MqttConnectProperties()

        connectProperties.topicAliasMaximum = 0

        connectProperties.sessionExpiryInterval = 0

        connectProperties.receiveMaximum = 100

        connectProperties.maximumPacketSize = 500

        mqtt5!.connectProperties = connectProperties

        mqtt5!.username = ""

        mqtt5!.password = ""

        mqtt5!.willMessage = CocoaMQTT5Message(topic:

"delhivery/mts/v3/location-data/preprod", string: "dieout")

        mqtt5!.keepAlive = 60

        mqtt5!.delegate = *self*

        mqtt5!.enableSSL = *true*

        mqtt5!.allowUntrustCACertificate = *true*

        mqtt5!.sslSettings = [

                GCDAsyncSocketManuallyEvaluateTrust: NSNumber(

booleanLiteral: true),

                GCDAsyncSocketUseCFStreamForTLS: NSNumber(booleanLiteral:

false),

                kCFStreamSSLPeerName *as* String: "" *as* NSString,

                GCDAsyncSocketSSLProtocolVersionMin: NSNumber(

integerLiteral: Int(SSLProtocol.tlsProtocol1.rawValue)),

                GCDAsyncSocketSSLProtocolVersionMax: NSNumber(

integerLiteral: Int(SSLProtocol.tlsProtocol12.rawValue)),

            ]

        //let clientCertArray = getClientCertFromP12File(certName:

"client-keycert", certPassword: "MySecretPassword")

        *let* clientCertArray = getClientCertFromP12File(certName:

"client", certPassword: @.***")

        *var* sslSettings: [String: NSObject] = [:]

        sslSettings[kCFStreamSSLCertificates *as* String] =

clientCertArray

        mqtt5!.sslSettings = sslSettings

    }

}

*enum* X509Error: Error {

    *case* privateKeyDoesNotMatchCertificate

    *case* cannotCreateP12Keystore

    *case* cannotOpenFileHandles

}

*func* mqttWebsocketsSetting() {

    *if* mqttVesion == "3.1.1" {

        *let* clientID = "CocoaMQTT-\(animal!)-" + String(ProcessInfo().

processIdentifier)

        *let* websocket = CocoaMQTTWebSocket(uri: "/mqtt")

        mqtt = CocoaMQTT(clientID: clientID, host: defaultHost, port:

8083, socket: websocket)

        mqtt!.username = ""

        mqtt!.password = ""

        mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string:

"dieout")

        mqtt!.keepAlive = 60

        mqtt!.delegate = *self*

    }*else* *if* mqttVesion == "5.0" {

        *let* clientID = "CocoaMQTT5-\(animal!)-" + String(ProcessInfo

().processIdentifier)

        *let* websocket = CocoaMQTTWebSocket(uri: "/mqtt")

        mqtt5 = CocoaMQTT5(clientID: clientID, host: defaultHost, port:

8083, socket: websocket)

        *let* connectProperties = MqttConnectProperties()

        connectProperties.topicAliasMaximum = 0

        connectProperties.sessionExpiryInterval = 0

        connectProperties.receiveMaximum = 100

        connectProperties.maximumPacketSize = 500

        mqtt5!.connectProperties = connectProperties

        mqtt5!.username = ""

        mqtt5!.password = ""

        *let* lastWillMessage = CocoaMQTT5Message(topic: "/will",

string: "dieout")

        lastWillMessage.contentType = "JSON"

        lastWillMessage.willExpiryInterval = .max

        lastWillMessage.willDelayInterval = 0

        lastWillMessage.qos = .qos1

        mqtt5!.willMessage = lastWillMessage

        mqtt5!.keepAlive = 60

        mqtt5!.delegate = *self*

    }

}

*func* mqttWebsocketSSLSetting() {

    *if* mqttVesion == "3.1.1" {

        *let* clientID = "CocoaMQTT-\(animal!)-" + String(ProcessInfo().

processIdentifier)

        *let* websocket = CocoaMQTTWebSocket(uri: "/mqtt")

        mqtt = CocoaMQTT(clientID: clientID, host: defaultHost, port:

8084, socket: websocket)

        mqtt!.enableSSL = *true*

        mqtt!.username = ""

        mqtt!.password = ""

        mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string:

"dieout")

        mqtt!.keepAlive = 60

        mqtt!.delegate = *self*

    }*else* *if* mqttVesion == "5.0" {

        *let* clientID = "CocoaMQTT5-\(animal!)-" + String(ProcessInfo

().processIdentifier)

        *let* websocket = CocoaMQTTWebSocket(uri: "/mqtt")

        mqtt5 = CocoaMQTT5(clientID: clientID, host: defaultHost, port:

8084, socket: websocket)

        *let* connectProperties = MqttConnectProperties()

        connectProperties.topicAliasMaximum = 0

        connectProperties.sessionExpiryInterval = 0

        connectProperties.receiveMaximum = 100

        connectProperties.maximumPacketSize = 500

        mqtt5!.connectProperties = connectProperties

        mqtt5!.enableSSL = *true*

        mqtt5!.username = ""

        mqtt5!.password = ""

        //mqtt5!.willMessage = CocoaMQTT5Message(topic: "/will",

string: "dieout")

        mqtt5!.keepAlive = 60

        mqtt5!.delegate = *self*

    }

}

*func* getClientCertFromP12File(certName: String, certPassword: String)

-> CFArray? {

    // get p12 file path

    *let* resourcePath = Bundle.main.path(forResource: certName, ofType:

"p12")

    *guard* *let* filePath = resourcePath, *let* p12Data = NSData(

contentsOfFile: filePath) else {

        print("Failed to open the certificate file: \(certName).p12")

        *return* *nil*

    }

    // create key dictionary for reading p12 file

    *let* key = kSecImportExportPassphrase *as* String

    *let* options : NSDictionary = [key: certPassword]

    *var* items : CFArray?

    *let* securityError = SecPKCS12Import(p12Data, options, &items)

    *guard* securityError == errSecSuccess *else* {

        *if* securityError == errSecAuthFailed {

            print("ERROR: SecPKCS12Import returned errSecAuthFailed.

Incorrect password?")

        } *else* {

            print("Failed to open the certificate file: \(certName).p12"

)

        }

        *return* *nil*

    }

    *guard* *let* theArray = items, CFArrayGetCount(theArray) > 0 *else*

{

        *return* *nil*

    }

    *let* dictionary = (theArray *as* NSArray).object(at: 0)

    *guard* *let* identity = (dictionary *as* AnyObject).value(forKey:

kSecImportItemIdentity as String) else {

        *return* *nil*

    }

    *let* certArray = [identity] *as* CFArray

    *return* certArray

}

}

extension ViewController: CocoaMQTT5Delegate {

*func* mqtt5(_ mqtt5: CocoaMQTT5, didReceiveDisconnectReasonCode

reasonCode: CocoaMQTTDISCONNECTReasonCode) {

    print("disconnect res : \(reasonCode)")

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didReceiveAuthReasonCode reasonCode:

CocoaMQTTAUTHReasonCode) {

    print("auth res : \(reasonCode)")

}

// Optional ssl CocoaMQTT5Delegate

*func* mqtt5(_ mqtt5: CocoaMQTT5, didReceive trust: SecTrust,

completionHandler: @.**** (Bool) -> Void) {

    TRACE("trust: \(trust)")

    /// Validate the server certificate

    ///

    /// Some custom validation...

    ///

    /// if validatePassed {

    ///     completionHandler(true)

    /// } else {

    ///     completionHandler(false)

    /// }

    completionHandler(*true*)

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didConnectAck ack:

CocoaMQTTCONNACKReasonCode, connAckData: MqttDecodeConnAck?) {

    TRACE("ack: \(ack)")

    *if* ack == .success {

        *if*(connAckData != *nil*){

            print("properties maximumPacketSize: \(String(describing:

connAckData!.maximumPacketSize))")

            print("properties topicAliasMaximum: \(String(describing:

connAckData!.topicAliasMaximum))")

        }

        mqtt5.subscribe("chat/room/animals/client/+", qos:

CocoaMQTTQoS.qos0)

        //or

        //let subscriptions : [MqttSubscription] =

[MqttSubscription(topic: "chat/room/animals/client/+"),MqttSubscription(topic: "chat/room/foods/client/+"),MqttSubscription(topic: "chat/room/trees/client/+")]

        //mqtt.subscribe(subscriptions)

        *let* chatViewController = storyboard?.instantiateViewController

(withIdentifier: "ChatViewController") as? ChatViewController

        chatViewController?.mqtt5 = mqtt5

        chatViewController?.mqttVersion = mqttVesion

        navigationController!.pushViewController(chatViewController!,

animated: true)

    }

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didStateChangeTo state:

CocoaMQTTConnState) {

    TRACE("new state: \(state)")

    *if* state == .disconnected {

    }

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didPublishMessage message:

CocoaMQTT5Message, id: UInt16) {

    TRACE("message: \(message.description), id: \(id)")

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didPublishAck id: UInt16, pubAckData:

MqttDecodePubAck?) {

    TRACE("id: \(id)")

    *if*(pubAckData != *nil*){

        print("pubAckData reasonCode: \(String(describing:

pubAckData!.reasonCode))")

    }

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didPublishRec id: UInt16, pubRecData:

MqttDecodePubRec?) {

    TRACE("id: \(id)")

    *if*(pubRecData != *nil*){

        print("pubRecData reasonCode: \(String(describing:

pubRecData!.reasonCode))")

    }

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didPublishComplete id: UInt16,

pubCompData: MqttDecodePubComp?){

    TRACE("id: \(id)")

    *if*(pubCompData != *nil*){

        print("pubCompData reasonCode: \(String(describing:

pubCompData!.reasonCode))")

    }

}

*func* mqtt5(_ mqtt5: CocoaMQTT5, didReceiveMessage message:

CocoaMQTT5Message, id: UInt16, publishData: MqttDecodePublish?){

    *if*(publishData != *nil*){

        print("publish.contentType \(String(describing: publishData!.

contentType))")

    }

    TRACE("message: \(message.string.description), id: \(id)")

    *let* name = NSNotification.Name(rawValue: "MQTTMessageNotification"

}

extension ViewController: CocoaMQTTDelegate {

// Optional ssl CocoaMQTTDelegate

*func* mqtt(_ mqtt: CocoaMQTT, didReceive trust: SecTrust,

completionHandler: @.**** (Bool) -> Void) {

    TRACE("trust: \(trust)")

    /// Validate the server certificate

    ///

    /// Some custom validation...

    ///

    /// if validatePassed {

    ///     completionHandler(true)

    /// } else {

    ///     completionHandler(false)

    /// }

    completionHandler(*true*)

}

*func* mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {

    TRACE("ack: \(ack)")

    *if* ack == .accept {

        mqtt.subscribe("chat/room/animals/client/+", qos:

CocoaMQTTQoS.qos1)

        *let* chatViewController = storyboard?.instantiateViewController

(withIdentifier: "ChatViewController") as? ChatViewController

        chatViewController?.mqtt = mqtt

        chatViewController?.mqttVersion = mqttVesion

        navigationController!.pushViewController(chatViewController!,

animated: true)

    }

}

*func* mqtt(_ mqtt: CocoaMQTT, didStateChangeTo state:

CocoaMQTTConnState) {

    TRACE("new state: \(state)")

}

*func* mqtt(_ mqtt: CocoaMQTT, didPublishMessage message:

CocoaMQTTMessage, id: UInt16) {

    TRACE("message: \(message.string.description), id: \(id)")

}

*func* mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {

    TRACE("id: \(id)")

}

*func* mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message:

CocoaMQTTMessage, id: UInt16 ) {

    TRACE("message: \(message.string.description), id: \(id)")

    *let* name = NSNotification.Name(rawValue: "MQTTMessageNotification"

}

extension ViewController: UITabBarControllerDelegate {

// Prevent automatic popToRootViewController on double-tap of

UITabBarController

*func* tabBarController(_ tabBarController: UITabBarController,

shouldSelect viewController: UIViewController) -> Bool {

    *return* viewController != tabBarController.selectedViewController

}

*func* tabBarController(_ tabBarController: UITabBarController,

didSelect viewController: UIViewController) {

    print("tabbar index: \(tabBarController.selectedIndex)")

}

}

extension ViewController {

*func* TRACE(_ message: String = "", fun: String = *#function*) {

    *let* names = fun.components(separatedBy: ":")

    *var* prettyName: String

    *if* names.count == 2 {

        prettyName = names[0]

    } *else* {

        prettyName = names[1]

    }

    *if* fun == "mqttDidDisconnect(_:withError:)" {

        prettyName = "didDisconnect"

    }

    print("[TRACE] [\(prettyName)]: \(message)")

}

}

extension Optional {

// Unwrap optional value for printing log only

*var* description: String {

    *if* *let* self = *self* {

        *return* "\(self)"

    }

    *return* ""

}

} Regards, Rehan Hussain

On Fri, Apr 14, 2023 at 11:04 AM Rehan Hussain @.***> wrote:

Hello,

I have used your example code but tried to change with my p.12 certificate and port and urls and enclosing my sample please help. Regards, Rehan Hussain

On Sun, Apr 2, 2023 at 3:33 PM leeway @.***> wrote:

It seems the server closed this connection!

Could you please provide more details for analyzing this error? (i.e: More clearly code etc.)

— Reply to this email directly, view it on GitHub https://github.com/emqx/CocoaMQTT/issues/520#issuecomment-1493285563, or unsubscribe https://github.com/notifications/unsubscribe-auth/A6HBBRZTO4ZG4I67JYMFWKTW7FFHTANCNFSM6AAAAAAWKCTB3E . You are receiving this because you authored the thread.Message ID: @.***>

JaylinYu commented 1 year ago

Plz see log on the broker side