knolleary / pubsubclient

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

mqtt_publish_in_callback example not working using WiFiClient #836

Open pedroetb opened 3 years ago

pedroetb commented 3 years ago

I'm using ESP8266WiFi.h lib instead of Ethernet.h, and input message are never published at output topic.

Using local mosquitto broker, successfully receives hello world (so it's working), but nothing else.

Can't find anything in previous issues, it's is a known bug?

Here, the modified example:

/*
 Publishing in the callback

  - connects to an MQTT server
  - subscribes to the topic "inTopic"
  - when a message is received, republishes it to "outTopic"

  This example shows how to publish messages within the
  callback function. The callback function header needs to
  be declared before the PubSubClient constructor and the
  actual callback defined afterwards.
  This ensures the client reference in the callback function
  is valid.

*/

#include <SPI.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
IPAddress server(10, 0, 0, 100);

// Callback function header
void callback(char* topic, byte* payload, unsigned int length);

WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, ethClient);

// Callback function
void callback(char* topic, byte* payload, unsigned int length) {
  // In order to republish this payload, a copy must be made
  // as the orignal payload buffer will be overwritten whilst
  // constructing the PUBLISH packet.

  // Allocate the correct amount of memory for the payload copy
  byte* p = (byte*)malloc(length);
  // Copy the payload to the new buffer
  memcpy(p,payload,length);
  client.publish("outTopic", p, length);
  // Free the memory
  free(p);
}

void setup()
{

  WiFi.mode(WIFI_STA);
  WiFi.begin("ssid", "pass");
  delay(10000);
  if (client.connect("arduinoClient")) {
    client.publish("outTopic","hello world");
    client.subscribe("inTopic");
  }
}

void loop()
{
  client.loop();
}
mer30boy commented 3 years ago

Hello, I'm having the same issue Did you find a solution ?

pedroetb commented 3 years ago

Hi, not yet, but a delay of 1000ms after the publish inside the callback is my workaround. It's not a solution, because I need to avoid using delays.

mer30boy commented 3 years ago

I changed the callback function as follows:

void callback(char *topic, byte *payload, unsigned int length){
  delay(1000);
  Serial.println("new msg received ");
}

But the problem was not solved and I did not receive the message

pedroetb commented 3 years ago

I was talking about publishing a MQTT message from the callback function:

void callback(char *topic, byte *payload, unsigned int length){
  Serial.println("new msg received ");
  delay(1000);
  mqttClient.publish(...);
}

If you don't reach the callback function, your are stuck on a different point.