Pubsubclient: 1509521199: Socket error on client <XXXXXXXXXXXX>, disconnecting.

Created on 1 Nov 2017  Â·  10Comments  Â·  Source: knolleary/pubsubclient

Hi knolleary,

While I'm using your PubSubClient library, I'm encountering this issue for a very long time but I cannot find out why.

I'm using an Arduino Mega 2560 together with SIM 800C GPRS module, the libraries I'm using are TinyGSM & PubSubClient. I'm running a mosquitto MQTT server on the cloud (CentOS). On the server mosquitto_sub is used to subscribe the same topic as which Mega publish on (once a hour).
The set up runs well for about a few hours. After that no more message will be received on the server side subscription. But mqtt.connected() == 1 every time I check the connection status.

Checking the MQTT server output in verbose mode, I find when message chain brake, a log line like below will show:
1509521199: Socket error on client , disconnecting.

After that the server side subscription PINGREQ can still be received, but Mega PINGREQ is lost.
Before the socket error:
1509521182: Received PINGREQ from XXXXXXXXXX
1509521182: Sending PINGRESP to XXXXXXXXXX
1509521189: Received PINGREQ from mosqsub|3099-iZ2zeib3y0
1509521189: Sending PINGRESP to mosqsub|3099-iZ2zeib3y0

After the socket error:
1509521969: Received PINGREQ from mosqsub|3099-iZ2zeib3y0
1509521969: Sending PINGRESP to mosqsub|3099-iZ2zeib3y0

Arduino code:

void setup() {

  // Set console baud rate
  Serial.begin(115200, SERIAL_8N1);

  requestTopicString = requestTopicString + "/" + controllerID;

  InitSIM800();

  //MQTT Broker setup
  mqtt.setServer(broker, 1883);
  mqtt.setCallback(mqttCallback);

  delay(1000);

}


void loop() {

  if (mqtt.connected()) {
    failCount = 0;
    mqtt.loop();
  } else {
    // Reconnect every 10 seconds
    unsigned long t = millis();
    if (abs(t - lastReconnectAttempt) > 10000L) {
      lastReconnectAttempt = t;
      if (mqttConnect()) {
        lastReconnectAttempt = 0;
        SubscribeIncList();
      }
      else failCount ++;
    }
    if (failCount > 5) InitSIM800();
  }

  if (minute() >= 10 && minute() <= 59) resultUploaded = false;
  //if (minute() == 59) mqttConnect();
  if (hour() >= WORKING_HOUR_START && hour() <= WORKING_HOUR_END) {
    if (minute() <= 5 && resultUploaded == false) {
      GetReading();
      delay(1000);
      UploadResults();
      //if upload completed?
      resultUploaded = true;
    }
  }
  if (displayDebug == 1) {
    Serial.print(F("Looping..."));
    if (mqtt.connected())
    {
      Serial.print("Connected...");
    }
    else
    {
      Serial.print("Disconnected...");
    }
    String nowTime = "";
    nowTime = nowTime + month() + "/" + day() +  "/" + year() + " ";
    nowTime = nowTime + hour() + ":" + minute() + ":" + second();
    Serial.println(nowTime);
  }
  delay(5000);

}



boolean mqttConnect() {
  mqtt.disconnect();
  Serial.print(F("Connecting to "));
  Serial.print(broker);
  if (!mqtt.connect(clientID, mqttUser, mqttPass)) {
    Serial.println(F(" fail"));
    return false;
  }
  Serial.println(F(" OK"));
  return mqtt.connected();
}

Thanks very much if you could help me on this.

All 10 comments

Resolved it.
This is an insignificant issue but it cost me 1 week on this.
As shown in the log, the interval between 2 PINGREQ from Mega 2560 is 60s, which is too long as the MQTT_KEEPALIVE is set to 15.

The interval between 2 PINGREQ is controlled in pubsubclient::loop() function, so no need to put a delay in loop().

Hello,
I know it's been a long time, but since I have the same problem, I wonder how you solved it?

Change the parameter in pubsubclient.h library file, modify the MQTT_KEEP_ALIVE settings to a value larger than the PINGREQ interval.
Also, do not stuck the main loop as the mqtt.loop() function automatically send the PINGREQ.

Sent from Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 for Windows 10


From: rprediger notifications@github.com
Sent: Sunday, March 3, 2019 12:43:17 AM
To: knolleary/pubsubclient
Cc: winterzh; Author
Subject: Re: [knolleary/pubsubclient] 1509521199: Socket error on client , disconnecting. (#355)

Hello,
I know it's been a long time, but since I have the same problem, I wonder how you solved it?

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHubhttps://github.com/knolleary/pubsubclient/issues/355#issuecomment-468937061, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AXy2c-1jHEimrHE4Kh9skgYgZdUTNMpdks5vSqolgaJpZM4QN5bK.

Thanks,
Me I lost 3 days...
I use with STM32 DISCO-L475VG-IOT01A
Bye

I'm trying to solve the same issue and as I'm not too familiar with C and the MQTT protocol, I need to ask you for help:

So the recommendation is to change the following line directly in _PubSubClient.h_ of the library?

#define MQTTPINGREQ     12 << 4 // PING Request

Some questions about that:

  • what does 12 << 4 resolve to? I guess it's some bit shifting magic, but I never really understood that :-P
  • is there a way to change this value in my own sourcecode? In the world where I come from it is an anti pattern to fiddle around in the dependencies' sources.

MQTT_KEEPALIVE is also defined in _PubSubClient.h_:

// MQTT_KEEPALIVE : keepAlive interval in Seconds
#ifndef MQTT_KEEPALIVE
#define MQTT_KEEPALIVE 15
#endif

So isn't this a bug in _PubSubClient.h_ that needs to be fixed? Or the issue that emerges from these two settings something that depends on the settings of my MQTT broker? If so, what do I need to change in the settings of my broker so that I don't need to fiddle around in the library? I tried it with Mosquitto (like @winterzh) and HiveMQ, both with default settings.

Thanks in advance!

I started with the example _mqtt_esp8266_ that comes with the library and which is working for me without any changes in _PubSubClient.h_. I started to refactor it towards what I tried to do that didn't work.

Issues I've found so far, pt. 1:

You can't use WiFiClientSecure!

This will work:

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

This will throw error -2 on connect which will show up as Socket error on client <unknown>, disconnecting in _mosquitto_:

WiFiClientSecure wifiClient;
PubSubClient mqttClient(wifiClient);

Hi @frederikheld

So the recommendation is to change the following line directly in PubSubClient.h of the library?
#define MQTTPINGREQ 12 << 4 // PING Request

No - that is a constant for the PINGREQ packet type in the protocol. Changing its value will break the client.

The client is implemented to automatically send PINGREQ at a suitable frequency to ensure the keep alive timer doesn't fire - as long as client.loop() it called regularly.

If client.loop isn't called regularly, then the client risks timing out its connection with the broker. However, in that situation, the broker log would report the keep-alive timer had expired and the client was being disconnected. That is not the same as getting the Socket error message this issue is referring to.

To be honest, this issue is over 2 years old and it all comes down to how the library is being used and with what network client library.

I don't think there is value keeping this issue open because it isn't going to lead to any code changes in the library itself.

I think the fact you are getting the socket error message when you are trying to use the Secure client rather than the regular client, points to an issue with however you've configured the secure client.

I started with the example _mqtt_esp8266_ that comes with the library and which is working for me without any changes in _PubSubClient.h_. I started to refactor it towards what I tried to do that didn't work.

Issues I've found so far, pt. 1:

You can't use WiFiClientSecure!

This will work:

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

This will throw error -2 on connect which will show up as Socket error on client <unknown>, disconnecting in _mosquitto_:

WiFiClientSecure wifiClient;
PubSubClient mqttClient(wifiClient);

As knolleary pointed out this is not a library issue. client.loop() is called regularly, in which mqtt 'heartbeat' PINGREQ is sent.
However I can give you some advices on your set up:

  1. Do not stuck the client.loop() in main loop. In this loop the time between last sent and current time is calculated to see if it passed the INTERVAL you set.
  2. Make sure all you subprocesses are completed within the INTERVAL. e.g. server interval is 60s, the board receives something and deal with the payload info that takes up to 75s. the server will time out and the client disconnected. So set a server interval long enough to make sure something will be sent from the client with that interval
  3. If you have to use a subprocess that long, manually send some MQTTPINGREQ (which is 12 << 4 ) in it. This is NOT recommended.
  4. If you did everything correct and issue still persists, check if you have a reliable and stable module. It turned out all with the same settings, I still see server timeout on some cheaper ones, which never happens when I use decent modules on my product.

Hi @frederikheld

So the recommendation is to change the following line directly in PubSubClient.h of the library?
#define MQTTPINGREQ 12 << 4 // PING Request

No - that is a constant for the PINGREQ packet type in the protocol. Changing its value will break the client.

The client is implemented to automatically send PINGREQ at a suitable frequency to ensure the keep alive timer doesn't fire - as long as client.loop() it called regularly.

If client.loop isn't called regularly, then the client risks timing out its connection with the broker. However, in that situation, the broker log would report the keep-alive timer had expired and the client was being disconnected. That is not the same as getting the Socket error message this issue is referring to.

To be honest, this issue is over 2 years old and it all comes down to how the library is being used and with what network client library.

I don't think there is value keeping this issue open because it isn't going to lead to any code changes in the library itself.

I think the fact you are getting the socket error message when you are trying to use the Secure client rather than the regular client, points to an issue with however you've configured the secure client.

Thanks very much for your answer!

795 Here I have started a new issue. Same as what described here.

In the issue you see my code and I do not use any delays through the code. Still my esp8266 keeps disconnecting during this code.

Was this page helpful?
0 / 5 - 0 ratings