Azure IoT Edge 离线功能示例
Azure IoT Edge Offline capabilities Example
我对如何使用 IoT Edge 离线模式有点困惑。我以为它是开箱即用的!
我的物联网中心位于美国西部。当我断开我的 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);
}
}
}
为什么代码在 Init() 中创建了一个 moduleClient,但随后尝试在 SendEvent() 中使用 deviceClient 将消息直接发送到 IoT 中心?这完全绕过了边缘运行时(特别是 edgeHub),这有助于离线存储和转发。
我对如何使用 IoT Edge 离线模式有点困惑。我以为它是开箱即用的!
我的物联网中心位于美国西部。当我断开我的 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);
}
}
}
为什么代码在 Init() 中创建了一个 moduleClient,但随后尝试在 SendEvent() 中使用 deviceClient 将消息直接发送到 IoT 中心?这完全绕过了边缘运行时(特别是 edgeHub),这有助于离线存储和转发。