1. 程式人生 > >Azure IoT 技術研究系列3

Azure IoT 技術研究系列3

上篇博文中我們將模擬設備註冊到Azure IoT Hub中:我們得到了裝置的唯一標識。

本文中我們繼續深入研究,裝置到雲、雲到裝置通訊。

1. 在Azure IoT Hub中接收模擬裝置的訊息

讀取裝置到雲訊息的Event Hub相容終結點,使用 AMQP 協議。

我們新建一個Console控制檯工程:IoTServer,新增Nuget引用:WindowsAzure.ServiceBus

核心的名稱空間:using Microsoft.ServiceBus.Messaging;

核心類:EventHubClient 

通過EventHubClient建立一個EventHubReceiver,不間斷的接收裝置側的訊息。

1         static string connectionString = "HostName=IoTTest.*******;SharedAccessKeyName=iothubowner;SharedAccessKey=***";
2         static string iotHubD2cEndpoint = "messages/events";
3         static EventHubClient eventHubClient;

ReceiveMessagesFromDeviceAsync方法:

複製程式碼
 1         /// <summary>
2 /// 接收裝置側的訊息 3 /// </summary> 4 /// <param name="partition">分割槽</param> 5 /// <param name="ct">取消標識</param> 6 /// <returns>Task</returns> 7 private static async Task ReceiveMessagesFromDeviceAsync(string partition, CancellationToken ct) 8
{ 9 var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition, DateTime.UtcNow); 10 while (true) 11 { 12 if (ct.IsCancellationRequested) break; 13 EventData eventData = await eventHubReceiver.ReceiveAsync(); 14 if (eventData == null) continue; 15 16 string data = Encoding.UTF8.GetString(eventData.GetBytes()); 17 Console.WriteLine("Message received. Partition: {0} Data: '{1}'", partition, data); 18 19 //防止CPU被佔滿 20 Task.Delay(1).Wait(); 21 } 22 }
複製程式碼

Main函式中我們將整個IoTServer Run起來:

複製程式碼
 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("Azure IoT Hub 接收訊息..., Press Ctrl-C to exit.\n");
 4             eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, iotHubD2cEndpoint);
 5 
 6             var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
 7 
 8             CancellationTokenSource cts = new CancellationTokenSource();
 9 
10             System.Console.CancelKeyPress += (s, e) =>
11             {
12                 e.Cancel = true;
13                 cts.Cancel();
14                 Console.WriteLine("Exiting...");
15             };
16 
17             var tasks = new List<Task>();
18             foreach (string partition in d2cPartitions)
19             {
20                 tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
21             }
22 
23             Task.WaitAll(tasks.ToArray());
24         }
複製程式碼

2. 模擬裝置傳送訊息到Azure IoT Hub

我們同樣新建一個Console控制檯工程:Device,用於模擬向Azure IoT Hub 傳送訊息。

首先新增Nuget引用:Microsoft.Azure.Devices.Client,這個Nuget依賴的Nuget很多,不要著急,慢慢Install吧

核心的名稱空間:

using Microsoft.Azure.Devices.Client;
using Newtonsoft.Json;

核心類:

Microsoft.Azure.Devices.Client.DeviceClient

模擬裝置往Azure IoT Hub發訊息時,用到了裝置的Key(唯一標識)和IoT Hub HostName, 上篇博文中提到的主機名:Azure IoT 技術研究系列2-設備註冊到Azure IoT Hub

1         static DeviceClient deviceClient;
2         static string iotHubUri = "IoTTest.******";          //iot hub hostname
3         static string deviceKey = "+jDqO+Nu2g************="; //device key

新增一個迴圈向Azure IoT Hub傳送訊息的方法:SendDeviceToCloudMessagesAsync,1s 一條訊息

複製程式碼
 1         /// <summary>
 2         /// 迴圈向Azure IoT Hub傳送訊息
 3         /// </summary>
 4         private static async void SendDeviceToCloudMessagesAsync()
 5         {
 6             double avgWindSpeed = 10; // m/s
 7             Random rand = new Random();
 8 
 9             while (true)
10             {
11                 //傳送遙測資料
12                 double currentWindSpeed = avgWindSpeed + rand.NextDouble() * 4 - 2;
13                 var telemetryDataPoint = new
14                 {
15                     deviceId = "TeldPile001",
16                     windSpeed = currentWindSpeed
17                 };
18                 var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
19                 var message = new Message(Encoding.ASCII.GetBytes(messageString));
20 
21                 await deviceClient.SendEventAsync(message);
22                 Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
23 
24                 //1s 一條
25                 await Task.Delay(1000);
26             }
27         }
複製程式碼

然後,在Main函式中啟動模擬裝置傳送訊息:

複製程式碼
1         static void Main(string[] args)
2         {
3             Console.WriteLine("模擬裝置通訊...\n");
4             deviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey("TeldPile001", deviceKey), TransportType.Mqtt);
5 
6             SendDeviceToCloudMessagesAsync();
7             Console.ReadLine();
8         }
複製程式碼

 3. 啟動執行測試

在解決方案上設定雙啟動專案:Device和IoTServer

F5 Run:

可以發現,裝置側訊息傳送、Azure IoT Hub接收是同步的

我們檢視Azure Portal中的統計:

總結: 通過這兩篇博文,我們研究驗證了Azure IoT Hub 註冊裝置、裝置和雲之間的通訊,感覺整個Azure 的 IoT Hub還是非常好用、易用,比較容易理解和操作,基於PaaS層的IoT Hub,可以做很多有價值的設計和方案。

周國慶

2017/4/18