hivemq-mqtt-client icon indicating copy to clipboard operation
hivemq-mqtt-client copied to clipboard

Question. about user properties on automatic reconnect...

Open zhangheng1983 opened this issue 1 year ago • 6 comments

Checklist

  • [ ] I've searched the project's issues.
  • [ ] I've searched the project's discussions.

❓ Question

Hi,I set user properties as key is “client_info” to connect packet,when MQTT client connect, server can accept the connect packet with "client_info" properties. But, when client reconnect because of network error etc, the "client_info" properties is absent. Is the user properties cann't be set to reconnect packet?

  1)  In MQTT client code, I bind "client_info" properties as follow:
   final Mqtt5BlockingClient client = Mqtt5Client.builder()
                        .identifier(getClientId())
                        .serverHost(HOST)
                        .serverPort(PORT)
                        .simpleAuth()
                            .username(USERNAME)
                            .password(ByteBuffer.wrap(PASSWORD.getBytes(StandardCharsets.UTF_8)))
                        .applySimpleAuth()
                        .automaticReconnect()
                            .initialDelay(60, TimeUnit.SECONDS)
                            .maxDelay(60, TimeUnit.SECONDS)
                        .applyAutomaticReconnect()
                        .buildBlocking();
   final Mqtt5ConnectBuilder connectBuilder = Mqtt5Connect.builder()
                        .cleanStart(true)
                        // "client_info" properties
                        .userProperties().add("client_info", getClientInfo()).applyUserProperties()
                        .keepAlive(connectKeepAliveInSeconds());

    // That's ok, server can accept the first connect packet with "client_info" properties
    client.connect(connectBuilder.build());
    ......

    2)  In MQTT extensions, I handle the "client_info" properties as follows:
    Services.securityRegistry().setAuthenticatorProvider(input -> new ClientAuthenticator());
    ......
    public class ClientAuthenticator implements SimpleAuthenticator {
        @Override
         public void onConnect(final @NotNull SimpleAuthInput input, final @NotNull SimpleAuthOutput output) {
             // I cann't get "client_info" properties on reconnect
             final List<String> list = input.getConnectPacket().getUserProperties().getAllForName("client_info");
         }
    }

How can I set "client_info" properties on connect package and reconnect packet?

Is it possible to notify "client_info" through publish message?

📎 Additional context

zhangheng1983 avatar Aug 26 '24 07:08 zhangheng1983

Hi @zhangheng1983 - the reasoning for this is also explained here.

To set user properties on reconnect, you can add a addDisconnectedListener and configure the reconnector similar to here. With that you can then call:

connectWith().userProperties.add("client_info", getClientInfo()).applyUserProperties()

pglombardo avatar Sep 04 '24 07:09 pglombardo

Hi @zhangheng1983 - have you made any progress on this issue?

pglombardo avatar Sep 09 '24 09:09 pglombardo

what if the reconnection is handled by the automaticReconnect() from the original client? would I need to handle the reconnection manually ?

dr0-dev avatar Sep 23 '24 13:09 dr0-dev

Hi @zhangheng1983 - have you made any progress on this issue?

Thanks for your reply. My test result as follows:

  1. I add DisconnectedListener and ConnectedListener ...... final Mqtt5BlockingClient client = Mqtt5Client.builder() ...... .automaticReconnectWithDefaultConfig() .addDisconnectedListener(MainActivity.this) .addConnectedListener(MainActivity.this) .buildBlocking(); ...... @Override public void onDisconnected(@NonNull MqttClientDisconnectedContext context) { LOG.i(TAG, "on disconnected ..."); final Mqtt5ClientDisconnectedContext context5 = (Mqtt5ClientDisconnectedContext) context; context5.getReconnector() .reconnectWhen(getOAuthToken(), (token, throwable) -> { // first reconnect would be delayed 2s but OAuth server needs more time context5.getReconnector().connectWith().userProperties().add("client_info", getClientInfo()).applyUserProperties(); LOG.i(TAG, "set 'client_info' to reconnector ..."); }); }

    private static CompletableFuture<byte[]> getOAuthToken() { return CompletableFuture.supplyAsync(() -> { return new byte[] {1, 2, 3}; }); }

    @Override public void onConnected(MqttClientConnectedContext context) { LOG.i(TAG, "on connected ..."); }

  2. I start MQTT client connection, my MQTT broker do received the connection with "client_info"

  3. I CLOSE MY WIFI on device, yes it print "on disconnected ..." and "set 'client_info' to reconnector ..."

  4. I OPEN MY WIFI, it print "on connected ..."

  5. When reconnected, my MQTT broker have still not received 'client_info' user properties.

zhangheng1983 avatar Dec 26 '24 07:12 zhangheng1983

Now I handle this issue as follows:

  1. Close MQTT client auto reconnect
  2. Add a watch process to check MQTT client status, if it disconect, close it and recreate new MQTT client with 'client_info' Resolve the issue, Maybe it consume more resources.

zhangheng1983 avatar Dec 26 '24 07:12 zhangheng1983

what if the reconnection is handled by the automaticReconnect() from the original client? would I need to handle the reconnection manually ?

I think. If you configure automaticReconnect, you not need handle reconnection. Otherwise, you can handle reconnect in DisconnectedListener, or check the client status in additional thread.

zhangheng1983 avatar Dec 26 '24 08:12 zhangheng1983