New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connect_async does not connect when done after loop_start #848

Closed
igough opened this Issue Jun 6, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@igough

igough commented Jun 6, 2018

Mosquitto: 1.4.15.0ubuntu
Ubuntu: 16.04

Occasionally, when connect_async is issued shortly after loop_start, an immediate connection does not occur. When connect_async is issued prior to loop_start, a connection always immediately occur. In the code below, if you run it 3 or 4 times, it should fail at least once to connect within 1 second. This appears to be timing sensitive since commenting out the cout << getTime() << " Loop started" << endl; causes it to work.

#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <chrono>

#include <mosquitto.h>

#if defined(WIN32)
# include <windows.h>
# define sleep(x) Sleep((x)*1000)
#else
# include <unistd.h>
#endif

using namespace std;

static std::chrono::time_point<std::chrono::system_clock>  start;
static bool connected = false;

static double getTime(){
    auto end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end-start;
    return elapsed_seconds.count();
  }

void on_connect(struct mosquitto *mosq, void *obj, int rc ){
  cout << getTime() << " ++++++++++ Connected(" << rc << ")" << endl;
  connected = true;
}

void on_disconnect(struct mosquitto *mosq, void *obj, int rc ){
  cout << getTime() << " ---------- Disconnected(" << rc << ")" << endl;
  connected = false;
}

int main (int , char* [])
{
  start = std::chrono::system_clock::now();

  int ret = mosquitto_lib_init ();

  struct mosquitto* c = mosquitto_new ("con-test", true, 0);

  mosquitto_connect_callback_set(c, on_connect);
  mosquitto_disconnect_callback_set(c, on_disconnect);

#define FAILS
#ifndef FAILS
  ret = mosquitto_connect_async (c, "test.mosquitto.org", 1883, 4);
  cout << getTime() << " Connecting" << endl;
#endif

  ret = mosquitto_loop_start (c);
  if ( ret != 0 ){
    cout << getTime() << " Loop start error = " << ret << endl;
  } 
  cout << getTime() << " Loop started" << endl;

#ifdef FAILS
  ret = mosquitto_connect_async (c, "test.mosquitto.org", 1883, 4);
  cout << getTime() << " Connecting" << endl;
#endif

  for ( int i=0; i<200; i++ ){
    if ( connected ){
      cout << getTime() << " Publishing " << i << endl;
      mosquitto_publish( c,nullptr, "foo/bar", sizeof(int), &i, 0, false );
      break;
    } else {
      cout << getTime() << " Waiting for connect..." << endl;
    }
    sleep( 1 );
  }

  ret = mosquitto_disconnect (c);
  ret = mosquitto_loop_stop (c, false);
  ret = mosquitto_lib_cleanup ();
  return 0;
}

ralight added a commit that referenced this issue Aug 8, 2018

Fix connection problems when using mosquitto_connect_async().
The connection wouldn't always complete if mosquitto_loop_start() was
called before mosquitto_connect_async(). Closes #848.

Thanks to Ian Gough.

Bug: #848

Signed-off-by: Roger A. Light <roger@atchoo.org>

@ralight ralight added this to the 1.5.1 milestone Aug 8, 2018

@ralight

This comment has been minimized.

Show comment
Hide comment
@ralight

ralight Aug 8, 2018

Contributor

I've pushed a change that should fix this. Thanks for the example code, it is very much appreciated. If you want to give it a try please get the fixes branch and close the issue if you're happy.

Contributor

ralight commented Aug 8, 2018

I've pushed a change that should fix this. Thanks for the example code, it is very much appreciated. If you want to give it a try please get the fixes branch and close the issue if you're happy.

@igough

This comment has been minimized.

Show comment
Hide comment
@igough

igough Aug 8, 2018

Tested against the fixes branch. The behaviour is better than before in that it consistently connects within 2 seconds. Most of the time, on_connected is called within 300ms of program start, but occasionally, on_connected is called about 1.3 seconds after program start. Reconnect timeout? This longer delay is not ideal, but acceptable. Closing.

igough commented Aug 8, 2018

Tested against the fixes branch. The behaviour is better than before in that it consistently connects within 2 seconds. Most of the time, on_connected is called within 300ms of program start, but occasionally, on_connected is called about 1.3 seconds after program start. Reconnect timeout? This longer delay is not ideal, but acceptable. Closing.

@igough igough closed this Aug 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment