hivemq / hivemq-mqtt-client

HiveMQ MQTT Client is an MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and backpressure support
https://hivemq.github.io/hivemq-mqtt-client/
Apache License 2.0
847 stars 158 forks source link

automatic reconnect: Can't tell client to also resend user properties in SUBSCRIBE #536

Open MicWalter opened 2 years ago

MicWalter commented 2 years ago

Expected behavior

With the automatic reconnect the HiveMQ client will also resubscribe if the session was not present (MqttClientReconnector.DEFAULT_RESUBSCRIBE_IF_SESSION_EXPIRED = true).

Actual behavior

The problem is that if I my initial SUBSCRIBE had user properties I can't add them to the automatic RESUBSCRIBE.

To Reproduce

Steps

2022-07-20 10:39:15,368 INFO  - Received CONNECT from client 'test-client': <<<removed>>>, User Properties: [Name: 'test', Value: 'test']
2022-07-20 10:39:15,438 INFO  - Received SUBSCRIBE from client 'test-client': <<<removed>>>, User Properties: [Name: 'test', Value: 'test']

2022-07-20 10:39:19,553 INFO  - Sent DISCONNECT to client 'test-client': Reason Code: 'ADMINISTRATIVE_ACTION', Reason String: 'null', Server Reference: 'null', Session Expiry: 'null', User Properties: 'null'

2022-07-20 10:39:20,737 INFO  - Received CONNECT from client 'test-client': <<<removed>>>, User Properties: [Name: 'test', Value: 'test']
2022-07-20 10:39:20,791 INFO  - Received SUBSCRIBE from client 'test-client': <<<removed>>>, User Properties: 'null'

Reproducer code

@Test
public void test() throws Exception {

    final Mqtt5UserProperties connectProperties = Mqtt5UserProperties.builder()
            .add("test", "test").build();

    final Mqtt5AsyncClient client = Mqtt5Client.builder()
            .identifier("test-client")
            .addDisconnectedListener(context ->
                    TypeSwitch.when(context.getReconnector())
                            .is(Mqtt5ClientReconnector.class, mqtt5ClientReconnector -> {
                                final var builder = mqtt5ClientReconnector.connectWith();

                                builder.userProperties(connectProperties);
                                builder.applyConnect();

                               // client will also resubscribe when session was expired, but I don't have the option to add the properties again
                            }))
            .automaticReconnect()
            .applyAutomaticReconnect()
            .buildAsync();

    client.connectWith().userProperties(connectProperties).send().get();

    client.subscribeWith()
            .addSubscription()
            .topicFilter("test")
            .qos(MqttQos.AT_LEAST_ONCE)
            .applySubscription()
            .userProperties(Mqtt5UserProperties.builder().add("test", "test").build())
            .send()
            .get();

    TimeUnit.MINUTES.sleep(20);
}
    }

Details

Devenom1 commented 1 year ago

Yes this is a major issue. I have to manually call my connect method again that sets user properties on every disconnect.