bytebeamio / rumqtt

The MQTT ecosystem in rust
Apache License 2.0
1.63k stars 250 forks source link

Reconnection Issues with session #902

Closed newcomertv closed 2 months ago

newcomertv commented 2 months ago

Expected Behavior

When shutting down and reconnecting to the same Broker later the peer should allow the connection

Current Behavior

Sometimes using the mosquitto broker if the client program stop unexpectedly and later attempts to reconnect the connection is refused by the peer.

Failure Information (for bugs)

Probably not a bug, if its a config issue though it would be nice to document that for new users.

By changing the client_id this issue is fixed.

Checking running processes the previous process does not exist.

Restarting the docker of the broker without removing persistent storage does not fix the issue.

Context

This issue has been reproduced running both on Windows and Ubuntu 22.04 LTS. Across a list of the latest rustc versions.

The issue is intermittent and thus hard to reproduce.

I'm guessing there is a sane default on one of the two sides somehow keeping some kind of session or the sort which doesn't exist when creating the new process.

client connect code:

        /// Buffer capacity for the rumqttc client (10 messages)
        const CAPACITY: usize = 10;

        let l_url = format!("{}?client_id={}", p_config.broker, p_config.client_id);

        let Ok(mut l_mqttoptions) = MqttOptions::parse_url(&l_url) else {
            error!("Unable to parse URL : {:?}", l_url);
            return Err(());
        };

        l_mqttoptions.set_keep_alive(Self::TIMEOUT);

        if !p_config.username.is_empty() && !p_config.password.is_empty() {
            l_mqttoptions.set_credentials(&p_config.username, &p_config.password);
            info!("Setting username / password credentials");
        }

        log::warn!(
            "Clean session was set to: {:?}, override to false",
            l_mqttoptions.clean_session()
        );
        l_mqttoptions.set_clean_session(false);

        let (l_client, l_connection) = rumqttc::Client::new(l_mqttoptions, CAPACITY);
        self.client = Some(l_client);

Failure Logs

None :(

swanandx commented 2 months ago

on stopping the client process, mosquitto broker might be thinking it's still connected ( can be due to half open connections or something ) and might not allow connection with same client id again ( cuz as per it's state, that already exists ).

Not sure about the behaviour/working of mosquitto broker.

If you don't want to persist session, set the clean_session to true or you can decrease the keep alive interval and make sure that it's passed before reconnecting ( just an hack to get over half open connections ).

Closing this issue as it's not related to rumqtt, please feel free to comment/re-open if i missed something.

Thank you!

newcomertv commented 2 months ago

Thank you for the reply

I think closing the issue is valid

Anyhow the issue persists way longer than the keep alive interval. Additionally the desired behavior is using a persistent session so not doing that defeats the point.

I guess starting with a clean slate is better than not being able to connect at all as a fallback.

Unfortunately I can't run the whole thing on the rumqtt broker since a docker I don't control insists on connecting with an anonymous client_id every time which rumqtt did not seem to accept. I discovered that this feature is actually optional according to MQTT spec.

I'm guessing allowing anonymous connections isn't desired by the project, correct?

swanandx commented 2 months ago

wdym by anonymous connections / client_id?

If you mean empty client id like "", rumqttd ( broker ) do actually support assigning random client ids, it's merged to main but yet to be released.

BTW, you can't use empty/anonymous client ids and set clean session to false as per standards!

newcomertv commented 2 months ago

Ah good to know, I might just try that out then. Hopefully I'll get more logs out of it when it happens again.

yes, that makes total sense since randomizing the client means not being able to establish the same session twice.

I meant I'm depending on other projects done by other people that are closed source to me which rely on that particular feature without using sessions in their case.

Fingers crossed that rust to production works out in two weeks :sweat:

I ended up convincing the move to rust partially thanks to rumqtt actually :muscle: we used to use paho and C++.

swanandx commented 2 months ago

Fingers crossed that rust to production works out in two weeks :sweat:

All the best! It will work 🦀

BTW, we use rumqtt ( + wrapper around it to do some processing ) and Rust in production at Bytebeam ;)

I ended up convincing the move to rust partially thanks to rumqtt actually :muscle: we used to use paho and C++.

That's really awesome to hear! <3 Would love to know more about your use case if you are okie to share :)

newcomertv commented 2 months ago

We're running a bunch of servers locally on site for a fully automated parking installation with charging capabilities.

For this we have safety critical components the robot if you will. An orchestration/abstraction layer dealing with the various other components, redirecting and reinterpreting requests on the fly and a cloud link as to handle everything modern.

Our company does everything from the orchestration layer (me) upward up to the mobile app on this project. Since the safety guys apparently are big MQTT fans we ended up doing (almost) all local comms over MQTT.

Once everything runs and does well I'm sure there'll be a news article I can link to.

If you have an email for someone our business guys could talk to I'm sure we could establish friendly ties between companies. Anyhow feel free to send me an e-mail with your discord / WhatsApp / LinkedIn, or whatever, it never hurst to have another dev friend: nikolas.vonlonski@actimage.de

tekjar commented 2 months ago

We're running a bunch of servers locally on site for a fully automated parking installation with charging capabilities.

That's a very interesting usecase @newcomertv. We'd love to follow along your journey and see if there are possible collaboration opportunities

Here's my email for your business team: raviteja@bytebeam.io