jokerchu 发表于 2017-6-30 07:27:30

Azure IoT 技术研究系列3

  上篇博文中我们将模拟设备注册到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
页: [1]
查看完整版本: Azure IoT 技术研究系列3