1

I am investigating using MQTT (or AMQP) over a satellite connection. I am using MQTT over HTTPS towards an IoT Hub in Azure. Data is very expensive on satellite and I am trying to minimize the "idle" consumption of this connection. I can do this by changing how often the SaS token is renewed (default 1 hour) and the Keep Alive.

I am using the DeviceClient from the Microsoft.Azure.Devices NuGet package and there I can create a TransportSettings object and set the keep alive:

ITransportSettings transportSettings = new MqttTransportSettings(TransportType.Mqtt_WebSocket_Only)
{
    KeepAliveInSeconds = 90,
};

I then create the connection like this:

var client = DeviceClient.CreateFromConnectionString(connectionString , new[] { transportSettings });

What I experience is. If I omit the transport settings, the connections sends a keep alive every 5 seconds. If I set the keep alive to anything from 30 and above, it always sends the keep alive every 30 seconds. The description of the KeepAliveInSeconds property tells the default is 300 seconds: KeepAliveInSeconds property description

But my Wireshark trace tells a different story: Wireshark trace

When no MqttTransportSettings are given in the CreateFromConnectionString then it sends a keep alive every 5 seconds. When i add the settings, I can set the keep alive to 10 or 30 seocnds and this works, but if I set it to 90 like this example, it stays on the 30 seconds ()or so the Wireshark trace show). I tried to look in Azure if I can change anything there. And there are no settings like this on the IoT Hub.

So hopefully someone else experienced this and found a solution, from the client side to have a keep alive that is not sent every 5 or 30 seconds. My goal is like once ever 2-5 minutes.

asergaz
  • 996
  • 5
  • 17
nivs1978
  • 1,126
  • 14
  • 20
  • Since you are using MQTT over HTTPS I suspect that the KeepAliveInSeconds timeout will work differently than what's explained in the SDK (I am checking for a confirmation on this with product team): https://github.com/Azure/azure-iot-sdk-csharp/blob/main/device_connection_and_reliability_readme.md#timeout-controls – asergaz Oct 08 '21 at 11:21

2 Answers2

4

I am one of the devs on this SDK and I took a look at what is causing this.

Our WebSocket implementations use the ClientWebSocket class to create the connection. By default the ClientWebSocket has a KeepAliveInterval of 30 seconds. This KeepAliveInterval controls the WebSocket Ping request. This is different than our own KeepAliveInSeconds which is used for a specific PINGREQ packet in MQTT.

We do not expose a way to set the WebSocket KeepAliveInterval, but I created this issue to track and will discuss this with the team internally.

There is one caveat to setting the KeepAliveInSeconds. When it is used by the SDK it is divided by 4. See this documentation for details.

The client will send a ping request 4 times per keep-alive duration set. It will wait for 30 seconds for the ping response, else mark the connection as disconnected. Setting a very low keep-alive value can cause aggressive reconnects, and might not give the client enough time to establish a connection before disconnecting and reconnecting.

Just incase someone comes across this and is using AMQP and has a similar question. At the time of this answer, the AMQP service has an internal keep alive interval of 4 minutes that it imposes on the client. (This is also independent of the WebSocket KeepAliveInterval.) This interval cannot be changed as it's set at the service.

James Davis - MSFT
  • 1,736
  • 10
  • 12
  • Hello, I came across this thread while trying to figure out why the property `WebSocketKeepAlive` that was added since version 1.41.0 seem to cap off at `60s`, doesn't matter if I set it to `3min` or `10min`, I can see a ping-pong keep alive heartbeat being sent every `60s` while sniffing the network packets. I am trying my luck here, but do you happen to know why this is or how I can go about setting a longer value than 60s? Asking the same question below with your colleague below, David R. Williamson – K. Vu Jun 14 '23 at 06:48
2

The fix for this has been released with version 1.41.0.

  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/31759209) – Kuro Neko May 17 '22 at 03:39
  • 1
    My colleague above, James, gave those details. My update simply points to the release version of the fix. – David R. Williamson Aug 01 '22 at 17:30
  • Hello, I came across this thread while trying to figure out why the property `WebSocketKeepAlive` that was added since version 1.41.0 seem to cap off at `60s`, doesn't matter if I set it to `3min` or `10min`, I can see a ping-pong keep alive heartbeat being sent every `60s` while sniffing the network packets. I am trying my luck here, but do you happen to know why this is or how I can go about setting a longer value than 60s? – K. Vu Jun 14 '23 at 06:47