in iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs [463:516]
private static async void PingServerAsync(object ctx)
{
if (Logging.IsEnabled)
Logging.Enter(ctx, $"Scheduled check to see if a ping request should be sent.", nameof(PingServerAsync));
var context = (IChannelHandlerContext)ctx;
try
{
var self = (MqttIotHubAdapter)context.Handler;
if (!self.IsInState(StateFlags.Connected))
{
return;
}
TimeSpan idleTime = DateTime.UtcNow - self._lastChannelActivityTime;
if (Logging.IsEnabled)
Logging.Info(context, $"Idle time currently is {idleTime}.", nameof(PingServerAsync));
if (idleTime > self._pingRequestInterval)
{
// We've been idle for too long, send a ping!
await WriteMessageAsync(context, PingReqPacket.Instance, s_shutdownOnWriteErrorHandler).ConfigureAwait(true);
if (Logging.IsEnabled)
Logging.Info(context, $"Idle time was {idleTime}, so ping request was sent.", nameof(PingServerAsync));
// Wait to capture the ping response semaphore, which is released when a PINGRESP packet is received.
bool receivedPingResponse = await s_pingResponseSemaphore.WaitAsync(s_pingResponseTimeout).ConfigureAwait(true);
if (!receivedPingResponse)
{
if (Logging.IsEnabled)
Logging.Info(context, $"The ping response wasn't received in {s_pingResponseTimeout}, will shut down.", nameof(PingServerAsync));
ShutdownOnErrorAsync(context, new TimeoutException($"The ping response wasn't received in {s_pingResponseTimeout}"));
}
if (Logging.IsEnabled)
Logging.Info(context, $"Ping response was received successfully.", nameof(PingServerAsync));
}
self.ScheduleKeepConnectionAliveAsync(context);
}
catch (Exception ex) when (!ex.IsFatal())
{
if (Logging.IsEnabled)
Logging.Error(context, $"A non-fatal exception occurred while sending a ping request, will shut down: {ex}", nameof(ConnectAsync));
ShutdownOnErrorAsync(context, ex);
}
if (Logging.IsEnabled)
Logging.Exit(ctx, $"Scheduled check to see if a ping request should be sent.", nameof(PingServerAsync));
}