Azure IoT Edge离线功能示例

时间:2019-02-28 18:55:47

标签: azure-iot-hub azure-iot-edge

我对如何使用IoT Edge离线模式有些困惑。我虽然是开箱即用的!

我的IoT中心的位置在美国西部。当我将Edge设备与网络断开连接时,什么也没有发生。在线重新连接后,数据不会保存或重新发送。

我只有一个模块将数据发送到IoT中心,我可以看到数据通过Device Explorer Twin应用程序流动,并将数据保存在数据库中。

断开连接后,等待5分钟并重新连接,但在数据库中看不到我在脱机模式下尝试发送的数据。 离线时所有消息均丢失(我正在按日期时间戳对消息进行排序)。

我错过了配置吗?

有人知道为什么离线模式对我不起作用吗? 我正在使用Iot Edge Runtime v1.0.6和Windows容器。

这是我的测试模块的源代码:

using Microsoft.Azure.Devices.Client;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Runtime.Loader;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    class Program
    {

        static int monitoringInterval { get; set; } = 60;// 60 seconds
        static System.Timers.Timer testTimer;
        static ModuleClient ioTHubModuleClient;

        static void Main(string[] args)
        {
            Init().Wait();

            StartTestTimer();

            // Wait until the app unloads or is cancelled
            var cts = new CancellationTokenSource();
            AssemblyLoadContext.Default.Unloading += (ctx) => cts.Cancel();
            Console.CancelKeyPress += (sender, cpe) => cts.Cancel();
            WhenCancelled(cts.Token).Wait();
        }

        /// <summary>
        /// Handles cleanup operations when app is cancelled or unloads
        /// </summary>
        public static Task WhenCancelled(CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource<bool>();
            cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).SetResult(true), tcs);
            return tcs.Task;
        }

        /// <summary>
        /// Initializes the ModuleClient and sets up the callback to receive
        /// messages containing temperature information
        /// </summary>
        static async Task Init()
        {
            AmqpTransportSettings amqpSetting = new AmqpTransportSettings(TransportType.Amqp_Tcp_Only);
            ITransportSettings[] settings = { amqpSetting };

            // Open a connection to the Edge runtime
            ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
            await ioTHubModuleClient.OpenAsync();
            Console.WriteLine("IoT Hub module client initialized.");
        }


        static void StartTestTimer()
        {
            Console.WriteLine("Start Monitoring Timer: " + monitoringInterval + " seconds");

            // Set up a timer that triggers every minute.
            testTimer = new System.Timers.Timer();
            testTimer.Interval = monitoringInterval * 1000; // 60 seconds
            testTimer.Elapsed += new System.Timers.ElapsedEventHandler(SendEvent);
            testTimer.Start();

            SendEvent(null, null);
        }


        async static void SendEvent(object sender, System.Timers.ElapsedEventArgs args)
        {
            DateTime today = DateTime.Now;
            Console.WriteLine("[" + today + "] Send Data has started...");

            try
            {                
                //IoT device connection string
                string connectionString = "HostName=xxxxxx.azure-devices.net;DeviceId=IOT-Device1;SharedAccessKey=ett8xxxxxxxxx";

                // Connect to the IoT hub using the MQTT protocol
                DeviceClient _DeviceClient = DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt);
                _DeviceClient.OperationTimeoutInMilliseconds = 10000;

                Dictionary<string, Object> telemetryDataPoint = new Dictionary<string, Object>();

                string dateTime = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
                telemetryDataPoint.Add("DateTime", dateTime);               

                string messageString = JsonConvert.SerializeObject(telemetryDataPoint);
                Message message = new Message(Encoding.ASCII.GetBytes(messageString));

                // Send the telemetry message
                Console.WriteLine("\n*> Sending message: {0}",  messageString);
                await _DeviceClient.SendEventAsync(message).ConfigureAwait(false);
                Console.WriteLine("Message sent!");

            }
            catch (Exception e)
            {
                Console.WriteLine("Message not sent. Connection error to Iot Hub:" + e.Message);
            }

        }

    }

1 个答案:

答案 0 :(得分:2)

为什么代码在Init()中创建moduleClient,然后尝试使用SendEvent()中的deviceClient直接向IoT中心发送消息?这将完全绕过边缘运行时(特别是edgeHub),这有助于离线存储和转发。

以下是执行此操作的正确方法的示例:https://github.com/Azure/iotedge/blob/ad41fec507bb91a2e57a07cd32e287ada0ca08d8/edge-modules/SimulatedTemperatureSensor/src/Program.cs#L95