上篇博文中我們將模擬設備註冊到Azure IoT Hub中:我們得到了設備的唯一標識。 Azure IoT 技術研究系列2-設備註冊到Azure IoT Hub 本文中我們繼續深入研究,設備到雲、雲到設備通信。 1. 在Azure IoT Hub中接收模擬設備的消息 讀取設備到雲消息的Event H ...
上篇博文中我們將模擬設備註冊到Azure IoT Hub中:我們得到了設備的唯一標識。
Azure IoT 技術研究系列2-設備註冊到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