上篇博文中我们将模拟设备注册到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 string iotHubD2cEndpoint = messages/events3 static EventHubClient eventHubClient;
ReceiveMessagesFromDeviceAsync方法:
1 /// <summary> 2 /// 接收设备侧的消息 3 </summary> 4 <param name="partition">分区</param> 5 <param name="ct">取消标识 6 <returns>Task</returns> 7 private 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) break13 EventData eventData = await eventHubReceiver.ReceiveAsync(); 14 if (eventData == null) continue15 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 void Main([] 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) => 12 e.Cancel = 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)); 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
static DeviceClient deviceClient; string iotHubUri = IoTTest.******"; iot hub hostname string deviceKey = +jDqO+Nu2g************="; device key
添加一个循环向Azure IoT Hub发送消息的方法:SendDeviceToCloudMessagesAsync,1s 一条消息
循环向Azure IoT Hub发送消息 4 async void SendDeviceToCloudMessagesAsync() 5 double avgWindSpeed = 10; m/s 7 Random rand = Random(); 8 10 11 发送遥测数据 double currentWindSpeed = avgWindSpeed + rand.NextDouble() * 4 - 213 var telemetryDataPoint = new 14 { 15 deviceId = TeldPile00116 windSpeed = currentWindSpeed 17 }; 18 var messageString = JsonConvert.SerializeObject(telemetryDataPoint); var message = Message(Encoding.ASCII.GetBytes(messageString)); 20 21 deviceClient.SendEventAsync(message); 22 Console.WriteLine({0} > Sending message: {1}23 24 1s 一条 25 await Task.Delay(100026 27 }
然后,在Main函数中启动模拟设备发送消息:
2 3 Console.WriteLine(模拟设备通信...\n4 deviceClient = DeviceClient.Create(iotHubUri,new DeviceAuthenticationWithRegistrySymmetricKey(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