MQTT subscribe unreliable

I’m trying to send data over MQTT back to the arduino and ESP, but the subscribe function is completely unreliable. I’m using node-red to publish to my server and receive from the arduino, if I spam publish I’ll maybe receive 1 out of every 5 strings.

The publishing on the arduino side appears to work perfectly - I’ve had it posting at 5 second intervals and it comes through every time. I’ve now tried both the MQTT.h and PubSubClient libraries with the same result.

Anyone know what it could be? Code below

#include <MQTT.h>
#include <SPI.h>
#include "WiFiEsp.h"
#include "SoftwareSerial.h"
#ifndef HAVE_HWSERIAL1
#include "IPAddress.h"
SoftwareSerial Serial1(4,7); // RX, TX
#endif

char ssid[] = "";            // your network SSID (name)
char pass[] = "";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

WiFiEspClient net;
MQTTClient client;

unsigned long lastMillis = 0;

void connect() {

  Serial.print("\nconnecting...");
  while (!client.connect("arduino", "try", "try")) {
    Serial.print(".");
    delay(1000);
  }

  Serial.println("\nconnected!");

  client.subscribe("inputs");
  // client.unsubscribe("/hello");
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
client.publish("outputs", "oioi");
  // Note: Do not use the client in the callback to publish, subscribe or
  // unsubscribe as it may cause deadlocks when other things arrive while
  // sending and receiving acknowledgments. Instead, change a global variable,
  // or push to a queue and handle it in the loop after calling `client.loop()`.
}

void setup() {
   // initialize serial for debugging
  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);


  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");


  // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported
  // by Arduino. You need to set the IP address directly.
  client.begin("192.168.0.26", net);
  client.onMessage(messageReceived);

  connect();
}

void loop() {
  client.loop();

  if (!client.connected()) {
    connect();
  }

  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    client.publish("/hello", "world");
  }
}

I use PubSub in several projects and have no problems with it.
I don't know the MQTT.h library but the comment in the callback...

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
client.publish("outputs", "oioi");
  // Note: Do not use the client in the callback to publish, subscribe or
  // unsubscribe as it may cause deadlocks when other things arrive while
  // sending and receiving acknowledgments. Instead, change a global variable,
  // or push to a queue and handle it in the loop after calling `client.loop()`.
}

seems to escaped you.

trojanhawrs:
if I spam publish I'll maybe receive 1 out of every 5 strings.

MQTT has a quality of service (QoS) feature. When you need to ensure the message is received set QoS to "At least once" or higher.

There is a section on MQTT on the Wikipedia page if you like a short explanation.

Riva:
I use PubSub in several projects and have no problems with it.
I don't know the MQTT.h library but the comment in the callback...

seems to escaped you.

True, but I only added the publish as a debug after the serial prints were proving to be erratic. The serial print line was included in the example.

Klaus_K:
MQTT has a quality of service (QoS) feature. When you need to ensure the message is received set QoS to "At least once" or higher.

There is a section on MQTT on the Wikipedia page if you like a short explanation.

MQTT - Wikipedia

I have had a look at the QoS, pubSubClient only supports 0 qos for publishing and apparently 1 for subscribe - I've tried changing my function to

client.subscribe("inputs", 1);

. . .which is accepted by the compiler but doesn't appear to make any difference at all. 2 and 3 are also accepted despite the documentations saying 2 isnt supported and 3 is obviously non existent, so it does make me wonder if its doing anything at all