X-Ryl669 / eMQTT5

An embedded MQTTv5 client in C++ with minimal footprint, maximal performance
MIT License
65 stars 14 forks source link

Calling ConnectTo multiple times if the connection is not successful is not working #23

Closed Singa17 closed 2 months ago

Singa17 commented 3 months ago

Hi ,

I am having a scenario of trying to connect the broker again if connection is not successful.

Code is like below: Simple code

Network::Client::MQTTv5 myClient("NameOftheClient" , CallbackForMessage);

std::string serverHost(192.168.3.21); if( Network::Client::MQTTv5::ErrorType::Success != myClient.connectTo(serverHost.c_str(), 1883)) { //retry with other ipaddress std::string serverHost_new(192.168.3.221); if( Network::Client::MQTTv5::ErrorType::Success != myClient.connectTo(serverHost_new.c_str(), 1883)) { logger << "connection failed again" } }

For testing purpuse 192.168.3.21 is not mqtt broker and expecting connection to fail and result is same. 192.168.3.221 is a valid mqtt broker and expecting connection to success but it return already connected error.

Background analysis: on connectTo function, there is a below check. If connection is not open, try to connect.

    ScopedLock scope(impl->lock);
    if (impl->isOpen()) return ErrorType::AlreadyConnected;

For the first time(With invalid mqtt broker address), above check is false and continue to create a socket in impl->connectWith and return network error / timeout error since its a valid. For the second time (valid mqtt broker address) , above check is return true since the socket is already created first time and returning the already connected. My observation is the socket is not closed if the connection is not success in the below line:

    // Check we can contact the server and connect to it (not initial write to the server is required here)
    if (int ret = impl->connectWith(serverHost, port, useTLS))
        return ret == -7 ? ErrorType::TimedOut : ErrorType::NetworkError;

Can you help fix it or provide alternate solutions?

X-Ryl669 commented 3 months ago

Yes, nice find. I'll fix it soon. There are multiple cases that leaves the socket lingering (connected to any server but not in MQTT exchange). I'm currently rewriting the MQTT control loop for (upcoming) version 2, so it'll be fixed in this.

Meanwhile, you can destruct the client and it'll be closed (but this forces using a heap-based client instead).

X-Ryl669 commented 2 months ago

Please test last master branch, it should contain a fix for your issue. Please report if it doesn't work for your case.