flightonary / Moscapsule

MQTT Client for iOS written in Swift
MIT License
273 stars 69 forks source link

Can not receive messages #55

Open vladimirjankov opened 7 years ago

vladimirjankov commented 7 years ago

var mqttClient: MQTTClient? = nil let mqttConfig = MQTTConfig(clientId: "Sasa", host: "192.168.0.11", port: 1883, keepAlive: 60) override func viewDidLoad() { super.viewDidLoad() mqttClient = MQTT.newConnection(mqttConfig)

    print( "\(mqttClient?.isConnected)")
    mqttClient?.subscribe("ios/test", qos: 0)
    DispatchQueue.main.async {
        self.mqttConfig.onMessageCallback = { msg in
            print("asdasda \(msg.payloadString!)")
            sleep(1)

        }
        self.mqttConfig.onConnectCallback = { rtrn in
            print(rtrn)
        }
    }

}

it does not go in onMessageCallback...

AlexIzh commented 7 years ago

Do you call moscapsule_init()?

vladimirjankov commented 7 years ago

yes, i have tryed calling it didn't work

vladimirjankov commented 7 years ago

it says that I'm connected and i can subscribe but no call back function works

AlexIzh commented 7 years ago

Ah, just noticed. You configure callback functions after connect, but you should do it before. I mean, you should set callback functions to mqttConfig before MQTT.newConnection. Because when you call newConnection all callback functions will be set to low-level MQTT and when you change them, they aren't changed for low-level mqtt.

AlexIzh commented 7 years ago

So, did it help?

davidgs commented 7 years ago

I'm trying to use the sample code, and I am getting: 2017-06-01 08:52:38.795 MQTTest[12832:3234090] [MOSQUITTO] DEBUG Client cid sending CONNECT 2017-06-01 08:52:38.796 MQTTest[12832:3235398] [MOSQUITTO] DEBUG Client cid sending SUBSCRIBE (Mid: 1, Topic: mailbox/#, QoS: 2) 2017-06-01 08:52:38.796 MQTTest[12832:3235398] [MOSQUITTO] DEBUG Client cid sending DISCONNECT

So I get the connection, but it immediately disconnects and never receives any messages.

` moscapsule_init()

    // set MQTT Client Configuration

    let mqttConfig = MQTTConfig(clientId: "cid", host: "192.168.1.100", port: 1883, keepAlive: 60)

    mqttConfig.onConnectCallback = { returnCode in
        NSLog("Return Code is \(returnCode.description)")

    }

    mqttConfig.onMessageCallback = { mqttMessage in

        if mqttMessage.topic == "mailbox" {

            NSLog("MQTT Message received: payload=\(mqttMessage.payloadString)")

        }

    }

    // create new MQTT Connection

    let mqttClient = MQTT.newConnection(mqttConfig)

    mqttClient.subscribe("mailbox/#", qos: 2)

And the broker log: 1496321558: New connection from 192.168.1.106 on port 1883.

1496321558: New client connected from 192.168.1.106 as cid (c1, k60).

1496321558: Client cid disconnected. `

geekzj commented 6 years ago

Same problem occurred to me. Have you fixed it? How to deal with it? Appreciate your help.

shobhitka commented 6 years ago

@AlexIzh came to this issue in search of same problem and found your suggestion to initialise callback before connection solved my problem. Thanks. It worked for me.

smartAkash commented 6 years ago
     moscapsule_init()

   let mqttConfig = MQTTConfig(clientId: "k60", host:"192.168.0.11", port: 1883, keepAlive: 60)

     let objMQTTAuthOpts = MQTTAuthOpts(username: username, password: password)
      mqttConfig?.mqttAuthOpts = objMQTTAuthOpts

   let mqttClient = MQTT.newConnection(mqttConfig!)

  mqttConfig?.onConnectCallback = { returnCode in
        print("Return Code is \(returnCode.description)")

    }

    mqttConfig?.onMessageCallback = { mqttMessage in
        if mqttMessage.topic == "SS_BROKER_IOT_OFFICE" {
            print("MQTT Message received: payload=\(mqttMessage.payloadString)")
        }
    }

    mqttClient.connectTo(host: server, port: 1883, keepAlive: 3600)
    let deadlineTime = DispatchTime.now() + .seconds(20)
    DispatchQueue.main.asyncAfter(deadline: deadlineTime, execute: {
        mqttClient.subscribe(BROKE_SUBSCRIPTION_CHANNEL, qos: 0)
    })

Same problem occurred to me. Have you fixed it? How to deal with it. Client cid disconnected.

shobhitka commented 6 years ago

You need to call setting of onConnectCallback and onMessageCallback before MQTT.newConnection. Its at the time of newConnection that callbacks are set in my understanding.

smartAkash commented 6 years ago

@shobhitka i tried it but stil not working

shobhitka commented 6 years ago

Can you paste your current code here ?

smartAkash commented 6 years ago

@shobhitka

  let BROKE_SUBSCRIPTION_CHANNEL = "SS_BROKER"
    let server = "35.172.122.123"
    let username = "mosquitto_iot"
    let password = "smart@123"

    moscapsule_init()

    let mqttConfig:MQTTConfig? = MQTTConfig(clientId: "k60", host:server, port: 1883, keepAlive: 60)

    let objMQTTAuthOpts = MQTTAuthOpts(username: username, password: password)
    mqttConfig?.mqttAuthOpts = objMQTTAuthOpts

    mqttConfig?.onConnectCallback = { returnCode in
        print("Return Code is \(returnCode.description)")
    }

    mqttConfig?.onMessageCallback = { mqttMessage in
        if mqttMessage.topic == BROKE_SUBSCRIPTION_CHANNEL {
            print("MQTT Message received: payload=\(mqttMessage.payloadString)")
        }
    }

    let mqttClient = MQTT.newConnection(mqttConfig!)
    mqttClient.connectTo(host: server, port: 1883, keepAlive: 60)

    let deadlineTime = DispatchTime.now() + .seconds(10)
    DispatchQueue.main.asyncAfter(deadline: deadlineTime, execute: {
        mqttClient.subscribe(BROKE_SUBSCRIPTION_CHANNEL, qos: 2)
    })
bjpetit commented 6 years ago

I can't see how this code block is called. But, as the code above is written, the MQTTConfig and MQTT connection objects only live in the scope of this code block. Once this code block returns, these objects will go out of scope be torn down. I'd double check that your objects are staying in scope after the connection.

shobhitka commented 6 years ago

@smartAkash, as @bjpetit mentioned, this looks like maybe the issue, otherwise the sequence of initialisation looks okay.

TayyibFZ commented 6 years ago

import UIKit import Moscapsule import Foundation

class dataHubView: UIViewController{

@IBOutlet weak var humidityL: UILabel!
@IBOutlet weak var waterL: UILabel!
@IBOutlet weak var tempL: UILabel!
@IBOutlet weak var refreshM: UIButton!
@IBAction func backMain(_ sender: Any) {
    self.performSegue(withIdentifier: "backMainSegue" , sender: self)

}
@IBOutlet weak var backMain: UIButton!
@IBAction func refreshM(_ sender: Any) {
    print("TEST!")

    //mqttClient.connectTo(host: "10.0.0.40", port: 1883, keepAlive: 60)

}

override func viewDidLoad() {
    super.viewDidLoad()
     moscapsule_init()
     let mqttConfig = MQTTConfig(clientId: "iOS", host: "10.0.0.40", port: 1883, keepAlive: 60)
     mqttConfig.onConnectCallback = { returnCode in
     // DispatchQueue.main.async {
     if returnCode == ReturnCode.success {
     print("Connected!")
     }
     else {
     print("Error")
     }
     //  }
     }
     mqttConfig.onMessageCallback = { mqttMessage in
     // DispatchQueue.main.async {
     let deku = (String(describing: mqttMessage.payloadString))
     if mqttMessage.topic == "return/temp" {
     print("temp")
     self.tempL.text = deku
     } else if mqttMessage.topic == "return/water"{
     print("water")
     self.waterL.text = deku
     } else if mqttMessage.topic == "return/humid"{
     print("humid")
     self.humidityL.text = deku
     }
     // }
    }
    let mqttClient = MQTT.newConnection(mqttConfig)
    mqttClient.connectTo(host: "10.0.0.40", port: 1883, keepAlive: 9999)
    mqttClient.subscribe("return/temp", qos: 2)
    mqttClient.subscribe("return/water", qos: 2)
    mqttClient.subscribe("return/humid", qos: 2)
    backMain.layer.cornerRadius = backMain.frame.size.height/2
    backMain.layer.masksToBounds = true
    backMain.setGradientBackground(colorOne: Colors.white, colorTwo: Colors.red)
    refreshM.layer.cornerRadius = backMain.frame.size.height/2
    refreshM.layer.masksToBounds = true
    refreshM.setGradientBackground(colorOne: Colors.red, colorTwo: Colors.veryDarkGrey)
    view.setGradientBackground(colorOne: Colors.black, colorTwo: Colors.green)
    // Do any additional setup after loading the view, typically from a nib.
  /*
*/
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

I have a very similar issue with mine everything connects and subscribes but as soon as its done it disconnects

2018-05-16 18:01:52.266177-0700 Centurion[7956:3105281] [MOSQUITTO] DEBUG Client iOS sending CONNECT 2018-05-16 18:01:52.272348-0700 Centurion[7956:3105294] [MOSQUITTO] DEBUG Client iOS received CONNACK 2018-05-16 18:01:52.272702-0700 Centurion[7956:3105273] [MOSQUITTO] DEBUG Client iOS sending CONNECT 2018-05-16 18:01:52.273024-0700 Centurion[7956:3105276] [MOSQUITTO] DEBUG Client iOS sending SUBSCRIBE (Mid: 1, Topic: return/temp, QoS: 2) 2018-05-16 18:01:52.273324-0700 Centurion[7956:3105273] [MOSQUITTO] DEBUG Client iOS sending SUBSCRIBE (Mid: 2, Topic: return/water, QoS: 2) 2018-05-16 18:01:52.273524-0700 Centurion[7956:3105273] [MOSQUITTO] DEBUG Client iOS sending SUBSCRIBE (Mid: 3, Topic: return/humid, QoS: 2) 2018-05-16 18:01:52.273702-0700 Centurion[7956:3105273] [MOSQUITTO] DEBUG Client iOS sending DISCONNECT Connected!

smartAkash commented 6 years ago

@TayyibFZ Thanks for shared your code i checked and tested now it is connected but have problem of receiving msg whatever i subscribed not getting msg.....you can see my below code please help...

    moscapsule_init()
    let mqttConfig = MQTTConfig(clientId: "iOS", host: server, port: 1883, keepAlive: 120)
    let objMQTTAuthOpts = MQTTAuthOpts(username: username, password: password)
    mqttConfig.mqttAuthOpts = objMQTTAuthOpts
           mqttConfig.onConnectCallback = { returnCode in
          if returnCode == ReturnCode.success {
            print("Connected!")
           }else {
            print("Error")
           }
         }
          mqttConfig.onMessageCallback = { mqttMessage in
    //             DispatchQueue.main.async {
        let _ = (String(describing: mqttMessage.payloadString))
        if mqttMessage.topic == "BROKE_SUBSCRIPTION_CHANNEL" {
            print("BROKE_SUBSCRIPTION_CHANNEL")
        }
       //  }
    }
    let mqttClient = MQTT.newConnection(mqttConfig)
    mqttClient.connectTo(host: server, port: 1883, keepAlive: 9999)
    mqttClient.subscribe("BROKE_SUBSCRIPTION_CHANNEL", qos: 2)

you can see log it is connected but not receiving msg.....

 2018-05-17 05:44:26.529643+0100 SmartOffice[452:93494] [MOSQUITTO] DEBUG   Client iOS 
 sending CONNECT
 2018-05-17 05:44:26.832983+0100 SmartOffice[452:93494] [MOSQUITTO] DEBUG   Client iOS 
 sending CONNECT
 2018-05-17 05:44:26.833825+0100 SmartOffice[452:93494] [MOSQUITTO] DEBUG   Client iOS 
 sending SUBSCRIBE (Mid: 1, Topic: BROKE_SUBSCRIPTION_CHANNEL, QoS: 2)
 2018-05-17 05:44:26.834057+0100 SmartOffice[452:93494] [MOSQUITTO] DEBUG   Client iOS 
 sending DISCONNECT
 2018-05-17 05:44:26.834564+0100 SmartOffice[452:93516] [MOSQUITTO] DEBUG   Client iOS 
 sending CONNECT
bjpetit commented 6 years ago

@TayyibFZ, the reason this code disconnects right away is because the mqttClient (and mqttConfig) object only exists in the context of the viewDidLoad() method because they are declared in that method. Once viewDidLoad() completes this object will be torn down and the connection will be closed.

These objects, which you want to stay around, should be declared outside of viewDidLoad. You can run the rest of the code you have in that method, but you should declare mqttConfig and mqttClient in a spot where they will stick around, for example, either declare them in the ViewController object or globally.

smartAkash commented 6 years ago

@bjpetit Hi i have used separate that function is out side of viewDidLoad() it is connecting but not receiving msg whatever subscribed channels you can see my code above in comments....

TayyibFZ commented 6 years ago

I did a little bit of tinkering and finally got everything to work hank you very much @bjpetit. Also @smartAkash no entirely sure but try using your callbacks inside the viewDidLoad() and subscribing and connecting to your server thru a push button that fixed the problem with mine.

bjpetit commented 6 years ago

@TayyibFZ, glad to hear things are coming together.

@smartAkash, from the code block you posted, the calls look to be correct. And the logs show the connection and the subscribe. However, it looks like a disconnect is called right after the subscribe completes. So your connection is being closed down before any messages can come in. Since the mqttClient and mqttConfig objects are defined in this code block, they will disappear as soon as this code completes. When mqttClient is deinitialized, it will call disconnect, which is where the DISCONNECT in the logs is coming from. If, for example, you define those as global variables, and initialize them in the spot you are today, the connection should stay active until you call disconnect.