zoukankan      html  css  js  c++  java
  • 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.
    ");
     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("模拟设备通信...
    ");
    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

  • 相关阅读:
    HashMap 的数据结构
    JVM的内存区域划分
    分库分表的基本思想
    分表与分库使用场景以及设计方式
    千万数据的分库分表(一)
    用c++实现快速排序和归并排序
    如何查看python版本号?
    python的正则表达式
    python3的队列,比python2更好
    markdown如何插入代码?
  • 原文地址:https://www.cnblogs.com/tianqing/p/6726081.html
Copyright © 2011-2022 走看看