knolleary / pubsubclient

A client library for the Arduino Ethernet Shield that provides support for MQTT.
http://pubsubclient.knolleary.net/
MIT License
3.82k stars 1.47k forks source link

subscribe more than 5 topics in sequence #98

Open Pfannex opened 8 years ago

Pfannex commented 8 years ago

Hi,

at first I like to say thanks for your great work!

Right now I try to subscribe more than 5 topics in sequence.

//Loop until we're reconnected
  while (!mqtt_client.connected() && WiFi.status() == WL_CONNECTED) {
       Serial.print("WIFI-Status: ");
       //Serial.println(WiFi.status());
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (mqtt_client.connect(char_MQTT_DeviceName)) {
      Serial.println("connected");
      //broker_subcribe();

  mqtt_client.subscribe("36/Output/01");
  mqtt_client.subscribe("36/Output/02");
  mqtt_client.subscribe("36/Output/03");
  mqtt_client.subscribe("36/Output/04");
  mqtt_client.subscribe("36/Output/05");
  //mqtt_client.subscribe("36/Output/06");
  //mqtt_client.subscribe("36/Output/07");
  //mqtt_client.subscribe("36/Output/08");

Subscribing 5 topics work fine...... Subscribing more then 5 topics in sequence will force a disconnect from the broker.

I´m not shure where to search the fault:

Can anybody check this out... Thanks for your Help Pf@nne

Right now I work around with the wildcard option.

  mqtt_client.subscribe("36/Output/+");

But should the other method not also work?

Suxsem commented 8 years ago

I'm experiencing the same problem, but in my case the maximum subscribes are 4... 5 subscribes causes disconnect from broker. Did you find a solution?

knolleary commented 8 years ago

Some thoughts and suggestions. Do you have access to the broker logs to give any indication? Are there retained messages on those topics? Have you tried putting a small delay between calls? Try adding calls to client.loop between subscribe calls as well.

On Sat, 19 Dec 2015, 08:14 Suxsem notifications@github.com wrote:

I'm experiencing the same problem, but in my case the maximum subscribes are 4... 5 subscribes causes disconnect from broker. Did you find a solution?

— Reply to this email directly or view it on GitHub https://github.com/knolleary/pubsubclient/issues/98#issuecomment-165960019 .

Suxsem commented 8 years ago

Thanks for your support! I'm not at home but i will provide you mosquitto logs in about 5 hours. Yes all topics have retained messages. I have not tried to add the delay between calls. I'll do it. Thanks again!

chaeplin commented 8 years ago

I have tested subscribe more than 12 topics in sequence(retained msgs). No special logs in broker(mosquitto).

With delay in between subscribe, no luck(disconnected). edited With "adding calls to client.loop between subscribe calls", success(more than 5). edited

Pfannex commented 8 years ago

Moin,

Have you tried putting a small delay between calls?

100ms delay will have no effect

With "adding calls to client.loop between subscribe calls", success.

What does a "call" means? How to send a call"?

Do you have access to the broker logs to give any indication?

No special logs in broker(mosquitto).

Suxsem commented 8 years ago

@chaeplin and WITHOUT client.loop the client disconnects? Or also without client.loop you can subscribe to 12 topics without disconnect?

chaeplin commented 8 years ago

With client.loop() after each subscribe I can subscribe 12 topics without disconnect.

Suxsem commented 8 years ago

@chaeplin and what happens without client.loop() after each subscribe? The client disconnects?

chaeplin commented 8 years ago

If i use delay, can't subscribe more than 5 topics.

@Pfannex add client.loop(); after each mqtt_client.subscribe.

mqtt_client.subscribe("36/Output/01"); client.loop(); mqtt_client.subscribe("36/Output/02"); client.loop(); mqtt_client.subscribe("36/Output/03"); client.loop(); mqtt_client.subscribe("36/Output/04"); client.loop(); mqtt_client.subscribe("36/Output/05"); client.loop(); mqtt_client.subscribe("36/Output/06"); client.loop(); mqtt_client.subscribe("36/Output/07");

Pfannex commented 8 years ago

Right now I receive commands from highest institution. After that I will have a look on the communication with Wireshark.

Btw. does anyone uses MQTT with the ESP8266 WIFI-Module? I also got problems by sending a publish within a interrupt.

@chaeplin Thanks for this hint! I guessed that "call" means a Ping-procedure.

Suxsem commented 8 years ago

@knolleary WOW IT WORKS! GREAT! calling client.loop() after every subscribe solve the issue!

Should I continue to use client.loop() after every subscribe or do you think that you could put the client.loop() at the end of the client.subscribe procedure?

Pfannex commented 8 years ago

I also confirm, now it works impeccable!!! :+1: :+1: Maybe a good idea to implement it into the subscribe routine.

//MCP23017 OUTPUT 
const char* subcribe_MCP23017_OUT_topic[] ={"/DIGITAL/OUTPUT/01",   //#0
                                            "/DIGITAL/OUTPUT/02",   //#1
                                            "/DIGITAL/OUTPUT/03",   //#2
                                            "/DIGITAL/OUTPUT/04",   //#3
                                            "/DIGITAL/OUTPUT/05",   //#4
                                            "/DIGITAL/OUTPUT/06",   //#5
                                            "/DIGITAL/OUTPUT/07",   //#6
                                            "/DIGITAL/OUTPUT/08"    //#7
                                           };
//-------------------------------------------------------------------------------

void broker_subcribe() {

  for (int i = 0; i < (sizeof(subcribe_MCP23017_OUT_topic)/sizeof(int)); i++){
    mqtt_client.subscribe(addTopicHeader(subcribe_MCP23017_OUT_topic[i]));
    mqtt_client.loop();
    Serial.print("subscribe: ");
    Serial.println(addTopicHeader(subcribe_MCP23017_OUT_topic[i]));
  }
}
Suxsem commented 8 years ago

I have made some changes to the library (that includes loop() inside subscribe and publish routines, qos for publishes, on disconnected callback and other minor things). I will made a pull request tomorrow :)

Pfannex commented 8 years ago

:+1:

marvinroger commented 8 years ago

So calling loop() in the main loop is not sufficient? We also have to call it after a subscribe and a publish? Or is it a workaround?

knolleary commented 8 years ago

Loop needs to be called regularly to ensure the flow of packets. It is not necessary to call it after each publish. If you are calling subscribe multiple times in quick succession you may need to call loop so the client can start handling the messages that will start arriving.

When I get some time I'll look at whether the client can handle more of this itself.

marvinroger commented 8 years ago

Got it, thanks for the precision.

HW-Siew commented 8 years ago

Did anyone try secure connection with more than 5 topics subscribe? I added the client.loop after each subscribe, but it failed to subscribe more than 3.

jollymansart commented 7 years ago

what is meant by addTopicHeader in the above code.... I do not see any code to accommodate it in the language and I believe it to be a procedure.

Harsh-Pandey commented 7 years ago

RuntimeError: maximum recursion depth exceeded while calling a Python object Error occurred when I placed client.loop() after each subscribe. I am implementing using python.

knolleary commented 7 years ago

@Harsh-Pandey this isn't a python library...

Harsh-Pandey commented 7 years ago

@knolleary Are you talking about client.loop() or mqtt. I have my own implementation on python for mqtt. It works fine till 5 subscriptions , but fails to show the data from the 6th device as soon as I connect my 6th device and subscribe to it.

knolleary commented 7 years ago

Your comment talked about a python error and wasn't clear what that had to do with this library.

Your second comment provides a bit more information, but still not sure what you're asking.

Are your devices using this library and you have some python code subscribing to their messages?

Harsh-Pandey commented 7 years ago

@knolleary Yes, I am using this library with my ESP8266( Node MCU) and I have around 20 of them sending data to raspberry pi which is subscribing to these 20 ESP8266 on different topics. When I connect 5 Node MCU and subscribe to their respective topics , my raspberry pi is getting data from the 5 node mcu but as soon as connect my 6th node mcu , my raspberry pi doesn't receive the data from the 6th node mcu

knolleary commented 7 years ago

Ok, this issue is regarding subscribing, using this library, to more than 5 topics in one go. From your description it sounds like it's your python code doing the subscribing? In which case it will be a different issue to this.

Harsh-Pandey commented 7 years ago

Yes, my python code on the raspberry pi is doing the subscribing.Sure, will look to some other place to resolve this issue.Thanks for the assistance.

mblaise0 commented 5 years ago

Some thoughts and suggestions. Do you have access to the broker logs to give any indication? Are there retained messages on those topics? Have you tried putting a small delay between calls? Try adding calls to client.loop between subscribe calls as well.

On Sat, 19 Dec 2015, 08:14 Suxsem notifications@github.com wrote:

I'm experiencing the same problem, but in my case the maximum subscribes are 4... 5 subscribes causes disconnect from broker. Did you find a solution? — Reply to this email directly or view it on GitHub #98 (comment) .

Thanks alot for this hint, I have tried and it work to some extent. I have about 10 to 12 topics which am subscribed to but i noticed it doesn't respond always. I may be doing some thing wrong or leaving something out please i need assistence am very new to programming. below is my reconnect function: EthernetClient ethClient3; PubSubClient mqttClient3(ethClient3); char data1[500]; void reconnect() { // Loop until we're reconnected while (!mqttClient3.connected()) { Serial.println("Attempting MQTT connection..."); if (mqttClient3.connect("arduinoClient3")) { Serial.println("Has now reconnected!");

  mqttClient3.subscribe("homeAutomationAc01");
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationAc02");
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationAc03"); 
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationAc04");
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationLight01");
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationLight02");
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationLight03");
  mqttClient3.loop();

  mqttClient3.subscribe("homeAutomationLight04");
  mqttClient3.loop();

  mqttClient3.subscribe("authorityToChangePowerSourceDistribution");
  mqttClient3.loop();

}else {
  Serial.print("failed, rc = ");
  Serial.print(mqttClient3.state());
  Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
  delay_5s.repeat();

// delay(5000); } } }

and here is my callback:

void callback(char topic, byte payload, unsigned int length) {

//if(!mqttClient3.connected()){ // reconnect(); //} char data1[700]; DynamicJsonDocument doc(1024); EthernetClient ethClient3; PubSubClient mqttClient3(ethClient3); mqttClient3.setServer(server, 11883); Serial.println("Message arrived Topic: [" + (String)topic + "]");

for (int i=0;i<length;i++) { payloadActual = payloadActual + (char)payload[i]; Serial.print((char)payload[i]); } //the payload coming from the broker is being deserialized at this point, the arduino responds to all command from the intelliegein side from here String input = payloadActual; deserializeJson(doc, input); JsonObject obj = doc.as(); String id = obj["mId"];
String mBody = obj["mBody"];

//this topic closes all utility contactors to distribution
if (strcmp(topic,"homeAutomationAc01")==0){
      turnOnAc01();
}

if (strcmp(topic,"homeAutomationAc02")==0){
    turnOnAc02();
}

if (strcmp(topic,"homeAutomationAc03")==0){
    turnOnAc03();
}

if (strcmp(topic,"homeAutomationAc04")==0){
    turnOnAc04();
}

    //acknowledgement to change power source
if (strcmp(topic,"authorityToChangePowerSourceDistribution") == 0){
    acknowledgeAuthorityToChangePowerSource();
}
//Utility contactors

// if (strcmp(topic,"homeAutomationLight01")==0){ // turnOnLight01(); // }

if (strcmp(topic,"homeAutomationLight02")==0){
    turnOnLight02();
}

if (strcmp(topic,"homeAutomationLight03")==0){
    turnOnLight03();
}

if (strcmp(topic,"homeAutomationLight04")==0){
    turnOnLight04();

}

}

thanks in advance