Skip to content
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

No reconnect if broker not available during initial connect #1903

Open
becz opened this issue Nov 17, 2020 · 2 comments
Open

No reconnect if broker not available during initial connect #1903

becz opened this issue Nov 17, 2020 · 2 comments

Comments

@becz
Copy link

becz commented Nov 17, 2020

Hello,

after updating from 1.5.7 to 1.6.12 I have an issue with reconnection in case of an unavaiable broker durring initial connect.

Steps to reproduce:

  • Setup boker running on localhost
  • Stop broker
  • Start example project (with mosquitto_connect_async, mosquitto_loop_start)
  • Start broker

--> After starting the broker, the example project should connect with the broker but that is not happening.

It seems like the thread is stucked waiting for state beeing unequal mosq_cs_new:

if(state == mosq_cs_new){

Example program:

    #include <signal.h>
    #include <stdio.h>
    #include <string.h>
    #include <mosquitto.h>

    static int run = 1;

    void handle_signal(int s)
    {
        run = 0;
    }

    void connect_callback(struct mosquitto *mosq, void *obj, int result)
    {
        printf("Connected!\n");
    }

    void disconnect_callback(struct mosquitto *mosq, void *obj, int result)
    {
        printf("Disconnected! (%i)\n", result);
    }

    void message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
    {
        printf("Message!\n");
    }

    void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
    {
        printf("Log: %s\n", str);
    }

    int main(int argc, char *argv[])
    {
        struct mosquitto *mosq = NULL;
        char clientid[24]="myLoopTest";
        char *host = "localhost";
        uint32_t port = 1883;
        int rc = 0;
        int major,minor,bugfix;
        signal(SIGTERM, handle_signal);
        signal(SIGINT, handle_signal);

        mosquitto_lib_init();
        mosquitto_lib_version(&major,&minor,&bugfix);
        printf("library version: %i.%i.%i\n",major,minor,bugfix);
        mosq = mosquitto_new(clientid, true, NULL);
        
        if(mosq)
        {
            mosquitto_connect_callback_set(mosq, connect_callback);
            mosquitto_disconnect_callback_set(mosq, disconnect_callback);
            mosquitto_message_callback_set(mosq, message_callback);
            mosquitto_log_callback_set(mosq, my_log_callback);

            rc = mosquitto_connect_async(mosq, host, port, 10);
            printf("mosquitto_connect_async returned: %i (%s)\n",rc,mosquitto_strerror(rc));

            rc = mosquitto_loop_start(mosq);	
            printf("mosquitto_loop_start returned: %i (%s)\n",rc,mosquitto_strerror(rc));

            while(run==1)
            {
            }
            
            printf("\nExiting\n");
            mosquitto_destroy(mosq);
            mosquitto_lib_cleanup();
            return rc;
        }
    }

Best regards

@ralight
Copy link
Contributor

ralight commented Nov 18, 2020

This is the output I get:

./a.out 
library version: 1.6.12
Log: Client myLoopTest sending CONNECT
mosquitto_connect_async returned: 14 (Connection refused)
mosquitto_loop_start returned: 0 (No error.)

From where I'm sat, I have to say that the problem is that you're ignoring the error code from mosquitto_connect_async. It tells you exactly the problem. Do you get the same output, or a different result?

@becz
Copy link
Author

becz commented Nov 19, 2020

Hello Roger,

thank you for the feedback. I get exactly the same output but I am wondering why the connection is not established after starting the broker (Behaviour is not reproduceable with 1.5.7).

I have ignored the return value of mosquitto_connect_async on purpose (Maybe due to an misunderstanding of the API)

My understanding:

  1. mosquitto_connect_async should be called once (before or after mosquitto_loop_start) in order to request connection. If connect does not succeed the client goes to state "connection pending":
    mosquitto__set_state(mosq, mosq_cs_connect_pending);
  2. mosquitto_loop_start starts the background thread which continues to handle the further connection process and tries to reconnect is necessary.

Should mosquitto_connect_async be called continuously until success (broker available) in this case?

do
{
    rc =mosquitto_connect_async(mosq, host, port, 10);
    printf("mosquitto_connect_async returned: %i (%s)\n",rc,mosquitto_strerror(rc));
    sleep(5);
}
while(rc == MOSQ_ERR_ERRNO);

The use case is an embedded device which runs the client. The device may be started before the broker is available. In this case it should connect automatically once the broker is available.

PS: I get different behaviour if I call mosquitto_connect_async after mosquitto_loop_start:


library version: 1.6.12
mosquitto_loop_start returned: 0 (No error.)
Log: Client myLoopTest sending CONNECT
mosquitto_connect_async returned: 0 (No error.)
Disconnected! (14)
Log: Client myLoopTest sending CONNECT
Log: Client myLoopTest received CONNACK (0)
Connected!

The client will connect once the broker is available.

f00b4r0 added a commit to f00b4r0/rwchcd that referenced this issue Dec 6, 2023
And call it after mosquito_loop_start()

This enables "graceful" failure when the broker isn't available and its
host is specified as an IP address.

See:
- eclipse/mosquitto#1903
- https://stackoverflow.com/questions/69084846/async-mosquitto-client-trying-to-re-connect-with-mosquitto-broker
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants