hivemq-mqtt-client
hivemq-mqtt-client copied to clipboard
Question. about user properties on automatic reconnect...
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
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()
Hi @zhangheng1983 - have you made any progress on this issue?
what if the reconnection is handled by the automaticReconnect() from the original client? would I need to handle the reconnection manually ?
Hi @zhangheng1983 - have you made any progress on this issue?
Thanks for your reply. My test result as follows:
-
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 ..."); }
-
I start MQTT client connection, my MQTT broker do received the connection with "client_info"
-
I CLOSE MY WIFI on device, yes it print "on disconnected ..." and "set 'client_info' to reconnector ..."
-
I OPEN MY WIFI, it print "on connected ..."
-
When reconnected, my MQTT broker have still not received 'client_info' user properties.
Now I handle this issue as follows:
- Close MQTT client auto reconnect
- 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.
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.