Exemplo n.º 1
0
        public async Task <bool> InitializeDeviceClient(IEnumerable <TimeSpan> retryIntervals)
        {
            if (!string.IsNullOrWhiteSpace(_deviceId) &&
                !string.IsNullOrWhiteSpace(_macAddress))
            {
                var retryPolicy = Policy
                                  .Handle <UnauthorizedException>()
                                  .WaitAndRetryAsync(
                    retryIntervals,
                    async(ex, waitTime) =>
                {
                    _log.Warning("DeviceClient was unauthorized ({ErrorMessage}). Attempting to register via the DeviceService...", ex.Message);
                    try
                    {
                        var response = await _registerDeviceRequest(_deviceId)
                                       .PostAsync(null);

                        _log.Information("IoT Hub Registration response was: {Response} - {Reason}",
                                         response.StatusCode, response.ReasonPhrase);
                    }
                    catch (Exception e)
                    {
                        _log.Error(e, "Failed to register the device with IoT Hub.");
                    }

                    _log.Warning("Retrying after {WaitTime:hh\\:mm\\:ss\\.ffff}.", waitTime);
                });

                await retryPolicy.ExecuteAsync(async() =>
                {
                    await _deviceClient.OpenAsync(CancellationToken.None);
                    await _deviceClient.SendEventAsync(new Message().WithProperties(("message-type", "device-connected")), CancellationToken.None);
                }).ConfigureAwait(false);

                return(true);
            }
            else
            {
                _log.Warning("Corrupt Message / DeviceId value: {0},{1}", _deviceId, _macAddress);
                return(false);
            }
        }
Exemplo n.º 2
0
        public async Task Start(CancellationToken cts)
        {
            var           correlationId = Guid.NewGuid().ToString();
            IDeviceClient deviceClient  = null;
            var           stopwatch     = Stopwatch.StartNew();

            try
            {
                deviceClient = CreateDeviceClient();
                deviceClient.SetConnectionStatusChangesHandler(OnConnectionStatusChanged);
                deviceClient.OperationTimeoutInMilliseconds = deviceRunnerConfiguration.DeviceOperationTimeoutInMilliseconds;

                if (deviceRunnerConfiguration.DeviceRetryPolicy)
                {
                    deviceClient.SetRetryPolicy(new ExponentialBackoff(10, TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(10), TimeSpan.FromMilliseconds(500)));
                }
                else
                {
                    deviceClient.SetRetryPolicy(new NoRetry());
                }

                await deviceClient.OpenAsync();

                stopwatch.Stop();
                Logger.Log($"{deviceId}: deviceClient created: {stopwatch.ElapsedMilliseconds}ms (retryPolicy={deviceRunnerConfiguration.DeviceRetryPolicy}, operationTimeoutInMilliseconds={deviceClient.OperationTimeoutInMilliseconds})");
            }
            catch (Exception ex)
            {
                Logger.Log($"{deviceId}: deviceClient creation failed: {ex.Message}");
                return;
            }

            var  number           = 0;
            var  maxMsTwinUpdate  = 0L;
            var  numSlowTwin      = 0;
            long maxMsC2D         = 0;
            int  numSlowC2D       = 0;
            long maxMsSendEvent   = 0;
            int  numSlowSendEvent = 0;

            while (!cts.IsCancellationRequested)
            {
                number++;

                // Update Device Twin with increasing "Number"
                if (this.deviceRunnerConfiguration.UpdateTwin)
                {
                    try
                    {
                        var reportedProperties = new TwinCollection();
                        reportedProperties["Number"] = $"{correlationId}-{number}";
                        stopwatch.Restart();
                        Logger.Log($"{deviceId}: begin twins update {number}.");
                        await deviceClient.UpdateReportedPropertiesAsync(reportedProperties);

                        stopwatch.Stop();
                        if (maxMsTwinUpdate < stopwatch.ElapsedMilliseconds)
                        {
                            maxMsTwinUpdate = stopwatch.ElapsedMilliseconds;
                        }
                        if (stopwatch.ElapsedMilliseconds > 4000)
                        {
                            numSlowTwin++;
                        }
                        Logger.Log($"{deviceId}: twins updated {number}: {stopwatch.ElapsedMilliseconds}ms. Max: {maxMsTwinUpdate}ms. Delays: {numSlowTwin}");
                    }
                    catch (IotHubCommunicationException iotHubCommunicationException)
                    {
                        Logger.Log($"{deviceId}: iothub problem, waiting {deviceRunnerConfiguration.DelayAfterIotHubCommunicationError}ms. {iotHubCommunicationException.Message}");
                        await Task.Delay(deviceRunnerConfiguration.DelayAfterIotHubCommunicationError);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log($"{deviceId}: failed to get update twin. {ex.Message}");
                    }
                }


                if (this.deviceRunnerConfiguration.SendEvent)
                {
                    try
                    {
                        var message = new Message(Encoding.UTF8.GetBytes($"{correlationId}-{number}"));
                        message.CorrelationId = correlationId;
                        message.ContentType   = "application/json";
                        stopwatch.Restart();
                        Logger.Log($"{deviceId}: begin send event {number}.");
                        await deviceClient.SendEventAsync(message);

                        stopwatch.Stop();
                        if (maxMsSendEvent < stopwatch.ElapsedMilliseconds)
                        {
                            maxMsSendEvent = stopwatch.ElapsedMilliseconds;
                        }

                        if (stopwatch.ElapsedMilliseconds > 4000)
                        {
                            numSlowSendEvent++;
                        }
                        Logger.Log($"{deviceId}: send event {number}: {stopwatch.ElapsedMilliseconds}ms. Max: {maxMsSendEvent}ms. Delays: {numSlowSendEvent}");
                    }
                    catch (IotHubCommunicationException iotHubCommunicationException)
                    {
                        Logger.Log($"{deviceId}: iothub problem, waiting {deviceRunnerConfiguration.DelayAfterIotHubCommunicationError}ms. {iotHubCommunicationException.Message}");
                        await Task.Delay(deviceRunnerConfiguration.DelayAfterIotHubCommunicationError);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log($"{deviceId}: failed to send event. {ex.Message}");
                    }
                }


                if (this.deviceRunnerConfiguration.CloudToDeviceMessage)
                {
                    try
                    {
                        // Check Cloud-to-Device Message
                        Logger.Log($"{deviceId}: checking c2d message");
                        stopwatch.Restart();
                        Message c2dMsg = await deviceClient.ReceiveAsync(TimeSpan.FromMilliseconds(500));

                        stopwatch.Stop();

                        if (maxMsC2D < stopwatch.ElapsedMilliseconds)
                        {
                            maxMsC2D = stopwatch.ElapsedMilliseconds;
                        }

                        if (stopwatch.ElapsedMilliseconds > 4000)
                        {
                            numSlowC2D++;
                        }

                        Logger.Log($"{deviceId}: done checking c2d message: {stopwatch.ElapsedMilliseconds}ms. Max: {maxMsC2D}ms. Delays: {numSlowC2D}");

                        if (c2dMsg != null)
                        {
                            var c2dMsgBody = c2dMsg.GetBodyAsText();
                            Logger.Log($"{deviceId}: c2d message received '{c2dMsgBody}'");

                            if (deviceRunnerConfiguration.CheckPendingCloudToDeviceMessage)
                            {
                                stopwatch.Restart();
                                var pendingMessage = await deviceClient.ReceiveAsync(TimeSpan.FromMilliseconds(200));

                                stopwatch.Stop();

                                if (maxMsC2D < stopwatch.ElapsedMilliseconds)
                                {
                                    maxMsC2D = stopwatch.ElapsedMilliseconds;
                                }

                                if (stopwatch.ElapsedMilliseconds > 4000)
                                {
                                    numSlowC2D++;
                                }

                                Logger.Log($"{deviceId}: done checking pending c2d message: {stopwatch.ElapsedMilliseconds}ms. Max: {maxMsC2D}ms. Delays: {numSlowC2D}");

                                if (pendingMessage != null)
                                {
                                    var pendingMessageBody = pendingMessage.GetBodyAsText();
                                    Logger.Log($"{deviceId}: abandoning c2d message '{pendingMessageBody}'");
                                    await deviceClient.AbandonAsync(pendingMessage);

                                    Logger.Log($"{deviceId}: done abandoning c2d message '{pendingMessageBody}'");
                                }
                            }

                            if (deviceRunnerConfiguration.CompleteCloudToDeviceMessage)
                            {
                                Logger.Log($"{deviceId}: completing c2d message '{c2dMsgBody}'");
                                await deviceClient.CompleteAsync(c2dMsg);

                                Logger.Log($"{deviceId}: done completing c2d message '{c2dMsgBody}'");
                            }
                        }
                        else
                        {
                            Logger.Log($"{deviceId}: no c2d message received");
                        }
                    }
                    catch (IotHubCommunicationException iotHubCommunicationException)
                    {
                        Logger.Log($"{deviceId}: iothub problem, waiting {deviceRunnerConfiguration.DelayAfterIotHubCommunicationError}ms. {iotHubCommunicationException.Message}");
                        await Task.Delay(deviceRunnerConfiguration.DelayAfterIotHubCommunicationError);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log($"{deviceId}: failed to handle cloud to device message. {ex.Message}");
                    }
                }

                await Task.Delay(this.deviceRunnerConfiguration.DeviceLoopDelay);
            }
        }