hivemq-mqtt-client
hivemq-mqtt-client copied to clipboard
Need to have API to override socket keepalive settings
Problem or use case
In some case we need to have a possibility to setup our custom TCP keepalive settings for this client, but your code, which initializes a socket is static and I cannot modify it at all without re-building your client.
@Provides
static @NotNull Bootstrap provideBootstrap(
final @NotNull NettyEventLoopProvider nettyEventLoopProvider,
final @NotNull MqttChannelInitializer channelInitializer) {
return new Bootstrap().channelFactory(nettyEventLoopProvider.getChannelFactory())
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT)
.handler(channelInitializer);
}
Preferred solution or suggestions
You can add some additional config or system properties to override default OS values using this code:
clientBootstrap.option(ChannelOption.SO_KEEPALIVE, true);
clientBootstrap.option(NioChannelOption.of(ExtendedSocketOptions.TCP_KEEPIDLE), keepaliveTime);
clientBootstrap.option(NioChannelOption.of(ExtendedSocketOptions.TCP_KEEPCOUNT), keepaliveProbes);
clientBootstrap.option(NioChannelOption.of(ExtendedSocketOptions.TCP_KEEPINTERVAL), keepaliveInterval);
Hi @JavaSaBr Thank you for your feature request. This is definitely something we could add to the config. What would be the best way to specify the channel options? Exposing netty related classes in the API is not the best idea imho. What are your thoughts on this?
Hi @SgtSilvio ,
Thanks for the quick response.
I think it should be on the client configuration level during building like:
MqttClient.builder()
.identifier(clientId)
.socketConfig()
.keepAliveTime(60)
.keepAliveInterval(20)
.keepAliveProbes(3)
.applySocketConfig()
.useMqttVersion5()
.build()
.toAsync()
I think we should allow setting socket options in a more generic way. Directly using keepAlive settings can be confused with the MQTT keep alive.
something like:
MqttClient.builder()
.transportConfig()
.socketOptions(Map.of("TCP_KEEPIDLE", 60, "TCP_KEEPINTERVAL", 20))
.applyTransportConfig()
...
I think it's a good option for me as well.
This is a great feature request and a much anticipated feature !
On one side considering i.e. the AWS NLB with its 350 second TCP idle timeout (https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#connection-idle-timeout) that cannot be changed, but by either doing traffic on the application layer or - as possible with this feature - use TCP keepalives. As a side note: This is also something that could / should be done on the MQTT broker side to not having to configure all the clients.
But also considering devices optimized for power consumption with a TCP stack that does maintain a TCP connection and the required keepalives without fully waking the whole application.