深入了解 Windows Azure

Windows Azure 服务总线和物联网,第 2 部分

Bruno Terkaly
Ricardo Villalobos

下载代码示例

我们最后一列中 (msdn.microsoft.com/magazine/dn574801),我们讨论了当前技术景观机器到机器 (M2M) 计算,它是指互连设备,通常用于工业仪器仪表、 传感器或米窗体中的技术。负担得起和易于程序的微型计算机的扩散到了所谓的--物联网 (物联网),打开门到哪里可以控制或作为信息来源的用于生成事件甚至普通家电的情形扩大了这一概念。这种方式,它不难时它是补充冰箱,自动关闭窗帘,夜落或设置基于家庭习惯的温控器的时间发送警报。

我们还提出为使用 Windows Azure 服务总线设备连接,作为使用 VPN,当试图解决与部署大量的传感器或米有关的寻址能力、 安全和性能问题时的替代方法。这一点变得日益相关考虑,从商业内幕交易的最新双情报报告,将超过 90 亿连接直接与有关的联网 2018 年 (read.bi/18L5cg8)。

使用指定的服务总线队列或主题为设备提供优雅的方式,以纳入弹性和偶尔连接对于物联网的应用程序。在本文中,我们会走通过实际操作的 Windows Azure 实施,说明了这些概念,设计与设备队列,部署在云服务中的听力工作者角色的服务总线蓝图和编程执行命令的 Arduino 设备发送远程的移动客户端,如中所示图 1


图 1--物联网体系结构使用 Windows Azure 服务总线

如果你看看图中,Windows Azure 服务总线组件将成为的设计,提供身份验证、 消息分布和可扩展性,以支持多个设备,会将数据发送或接收远程命令的核心。服务总线是可用在所有的 Microsoft 数据中心提供 Windows Azure 服务,它由一个高度冗余的存储基础结构备份。此外,像所有其他 Windows Azure 的组件,它提供开放和容易理解其他接口和多个 Sdk (Microsoft.NET 框架、JAVA、 PHP、 红宝石,除其他外的) 建在它。

我们建议的体系结构,在设备"聊聊"上 Windows Azure 云服务,充当到服务总线的网关,为了简化其分配队列与沟通过程运行.NET 应用程序。这种方法充分使任何以前的专栏中所述的四个物联网通信模式:遥测、 调查、 命令和通知。在这里,我们就会实现的移动设备发送命令到另一个设备来执行行动方案 — — 在这种情况下,打开 LED 或关闭。此解决方案的好处之一是如果该设备是暂时处于脱机状态,它可以接命令时它会重新连接到互联网。您还可以设置在邮件中,避免在不方便的时候执行一项任务或计划要在将来的特定时间发送的消息的过期时间。

对于此示例,我们将使用该知名、 翔实的 Arduino 设备,如以前的专栏中所述。对于移动客户端部分的概念证明,我们将创建一个 Windows Phone 应用程序。

这里是我们简单的情形:

  1. Arduino 设备启动时,它将识别信号发送到运行在 Windows Azure 云服务上的网关应用程序。网关服务总线为创建队列设备以防它不存在,并建立 TCP 连接时,准备好要发送的命令。
  2. 一个 Windows Phone 应用程序发送命令到分配给该设备的 Windows Azure 服务总线队列。
  3. 邮件保留在队列中,直到捡到了网关应用程序,并将命令发送到 Arduino 设备通过已建立的 TCP 连接。
  4. Arduino 设备打开 LED 或关闭基于该命令。

让我们来看看这步骤,使这种情况发生,一个接一个。

步骤 1:创建 Windows Azure 服务总线 Namespace 使用您的 Windows Azure 凭据 (您可以请求在试用帐号 bit.ly/1atsgSa)、 登录到门户网站,然后单击服务总线节 (见 图 2)。选择创建选项,并输入您的命名空间的名称。然后,单击连接信息,在连接字符串框中,稍后你会需要复制的文本。


图 2 创建 Windows Azure 服务总线 Namespace

步骤 2:创建网关应用程序和部署到 Windows Azure 云服务 为网关应用程序,它从服务总线队列检索消息和中转到 Arduino 的设备命令,是代码下载中包含的代码 (可在 msdn.microsoft.com/magazine/msdnmag0314)。它基于工作的克莱门斯更广阔,他好心贡献他的指导和专门知识对这篇文章。他原来的项目可以发现在 bit.ly/L0uK0v

我们潜入此代码之前,请确保你有Visual Studio2013 安装,Windows Azure SDK 的.NET 版本 2.2 (bit.ly/JYXx5n)。该解决方案包括三个不同的项目:

  • ArduinoListener — — 包含主要的 WorkerRole 代码。
  • ConsoleListener — — ArduinoListener,为本地测试的控制台版本。
  • MSDNArduinoListener — — ArduinoListener 项目的 Windows Azure 部署。

如果您检查 ServiceConfiguration.cscfg 文件 (对于云和本地部署) 的 MSDNArduinoListener 项目,您将看到一种设置,将连接字符串存储到服务总线。在步骤 1 中获得的一个替换它的值。其余已经被配置的解决方案要工作,包括定义的端口 10100 从设备接收的连接。下一步,打开 WorkerRole.cs 文件,在 ArduinoListener 项目中,主代码所在的位置。

有四个主要部分来分析。

首先,创建的 TcpListener,并且接受来自设备的连接:

 

var deviceServer = new TcpListener(deviceEP);
deviceServer.Start(10);
try
{
  do
  {
    TcpClient connection = 
      await deviceServer.AcceptTcpClientAsync();
    if (connection != null)
    {      ...

一旦已建立与设备的连接,NetworkStream 定义和设置为侦听模式。 ReadBuffer 变量将包含发送 Arduino 的每个设备的标识符值:

NetworkStream deviceConnectionStream = connection.GetStream();
var readBuffer = new byte[64];
if (await deviceConnectionStream.ReadAsync(readBuffer, 0, 4) == 4)
{
  int deviceId = 
    IPAddress.NetworkToHostOrder(BitConverter.ToInt32(readBuffer, 0));
  ...

下一步,创建基于队列 deviceId 值 (在情况并不存在),和一条消息接收器对象定义 (见图 3)。 然后,设备队列接收器设置为异步模式到拉消息 (命令从队列)。 此队列将存储的移动设备如 Windows Phone 发送命令。

图 3 创建队列

var namespaceManager = 
  NamespaceManager.CreateFromConnectionString(
    RoleEnvironment.GetConfigurationSettingValue("serviceBusConnectionString"));
if (!namespaceManager.QueueExists(string.Format("dev{0:X8}", deviceId)))
{
  namespaceManager.CreateQueue(string.Format("dev{0:X8}", deviceId));
}
var deviceQueueReceiver = messagingFactory.CreateMessageReceiver(
  string.Format("dev{0:X8}", deviceId), ReceiveMode.PeekLock);
do
{
  BrokeredMessage message = null;
  message = await deviceQueueReceiver.ReceiveAsync();

当队列中接收消息时,它的内容检查和如果它匹配"ON"或"关闭"命令,信息写入与设备建立连接流 (见图 4)。

图 4 写入连接流

if (message != null)
{
  Stream stream = message.GetBody<Stream>();
  StreamReader reader = new StreamReader(stream);
  string command = reader.ReadToEnd();
  if (command != null)
  {
    switch (command.ToUpperInvariant())
    {
      case "ON":
        await deviceConnectionStream.WriteAsync(OnFrame, 0, 
            OnFrame.Length);
        await message.CompleteAsync();
        break;
      case "OFF":
        await deviceConnectionStream.WriteAsync(OffFrame, 0, 
            OffFrame.Length);
        await message.CompleteAsync();
        break;
    }
  }
}

请注意不从队列中移除消息 (message.Complete­异步) 除非到设备连接流的写操作都成功。 此外,为保持连接,设备预期将发送 ping 信号。 此概念验证的我们不期望从设备的确认,当它接收到消息时。 在生产系统中,但是,这将需要遵守的"命令"模式。

步骤 3:部署 Arduino­向云服务侦听程序 Windows Azure 项目ArduinoListener 部署到 Windows Azure 是极其简单。 Visual Studio2013年、 用鼠标右键单击在 MSDN 上­ArduinoListener 项目,然后选择发布选项。 你会发现发布 Windows Azure 应用程序向导在具体说明 bit.ly/1iP9g2p。 完成向导后,您最终位于 xyz.cloudapp 的云服务。 净。 你需要它下, 一步创建 Arduino 客户端时记录此名称。

步骤 4:程序的网关 (监听器) 谈谈 Arduino 设备Arduino 设备提供了丰富的接口可用于执行网络操作使用一个简单的 Web 客户端对象。 为我们的原型,我们决定使用 Arduino Uno R3 模型 (bit.ly/18ZlcM8),以及其相应的以太网屏蔽 (bit.ly/1do6eRD)。 要安装、 交互和程序使用 Windows 的 Arduino 设备,请按照指南 》 在 bit.ly/1dNBi9R。 你会很容易使用的 IDE (称为 Arduino 应用程序),你可以写程序 (称为草图) 使用 JavaScript,如中所示图 5

The Arduino Application
图 5 Arduino 中应用

图 6 显示草绘与 Arduino 侦听器相互作用在步骤 3 中创建并现已部署在 Windows Azure。

图 6 的 Arduino 设备代码

#include <SPI.h>#include <Ethernet.h>#include <StopWatch.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network,
// and it's optional if DHCP is enabled.
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xBC, 0xAE };
static const byte deviceId[] = { 0x00, 0x00, 0x00, 0x01 };
static const uint8_t ACK = 0x01;
static const int LED_PIN = 8;
int connected = 0;
EthernetClient client;
StopWatch stopWatch;
long pingInterval = 200000;
void setup() {  Serial.begin(9600);
  Serial.println("Initialized");
  Ethernet.begin(mac);
  pinMode(LED_PIN, OUTPUT);}
void turnLedOn(){  digitalWrite(LED_PIN, HIGH);}
void turnLedOff(){  digitalWrite(LED_PIN, LOW);}
void loop() {
        if ( connected == 0)  {
    Serial.println("Trying to connect");
    char* host = "xyz.cloudapp.net";
    client.setTimeout(10000);
    connected = client.connect(host, 10100);
    if (connected)     {
      Serial.println(
        "Connected to port, writing deviceId and waiting for commands...");
      client.write(deviceId, sizeof(deviceId));
      stopWatch.start();
    }
    else
    {
      Serial.println("Connection unsuccessful");
      client.stop();
      stopWatch.reset();
    }
  }
  if (connected == 1)
  {
    if (stopWatch.elapsed() > pingInterval)
    {
      Serial.println("Pinging Server to keep connection alive...");
      client.write(deviceId, sizeof(deviceId));
      stopWatch.reset();
       stopWatch.start();
    }
    byte buf[16];
    int readResult = client.read(buf, 1);
    if (readResult == 0)
     {
      Serial.println("Can't find listener, disconnecting...");
      connected = 0;
      stopWatch.reset();
    }
    else if (readResult == 1)
    {
      Serial.println("Data acquired, processing...");
      switch ( buf[0] )
      {
        case 1:
          Serial.println("Command to turn led on received...");
          turnLedOn();
          break;
        case 2:
           Serial.println("Command to turn led off received...");
          turnLedOff();
          break;
      }
      stopWatch.reset();
      stopWatch.start();
    }
  }
}

剪影为 Arduino 有两个主要部分:安装程序和循环。 安装程序部分中的说明都执行一次,而这是在初始化变量和建立的连接。 在我们的示例中,定义了以太网客户端和相关的值、 建立串行连接 (用于调试目的),和的 pin 连接,指示灯的位置被初始化为一个输出端口。

不断,执行循环节中的代码,它包括两个主要街区基于 Arduino 设备和运行在 Windows Azure 云计算服务的侦听器之间的 TCP 连接的状态:连接或断开连接。 为连接建立时,连接第一次启动秒表对象跟踪的时间过去了。 此外,设备标识符发送到侦听器,要用作队列的名称将存储消息和命令。

创建连接的至今已处理已建立连接之后的行为跟踪的时间的 Arduino 的代码块,pinging 侦听器每 200,000 的 ms,以保持连接还活着,没有命令收到时。 此代码还试图从监听器,当它到达时将数据放置到 buf 数组中读取数据。 如果检测到的值为"1",则指示灯处于打开状态,如果值为"2",处于关闭状态指示灯。 在每个命令后,秒表对象被重置。

一旦草绘已上载到该设备,代码运行在一个无限循环,Arduino 控制器试图连接到云服务上。 当连接时,它将转发的设备 id,这样的云服务就知道向哪个设备在说。 然后,代码开始读取输入从云服务,告诉该设备是否要打开或关闭 LED 灯 (在这种情况下,它连接至设备的数字端口 8)。

步骤 5:创建 Windows Phone 客户端发送到设备队列互动与设备很简单,将消息发送到设备队列。 我们在文章开头提到,Windows Azure 服务总线提供其余界面,允许您从多种编程语言与它交互。 因为有没有官方的 SDK 为 Windows Phone 开发者,我们使用来自 Windows Phone 社区,演示如何进行身份验证和与服务总线进行交互使用 HTTP 请求和 WebClient 对象的例子之一。 此外包括在代码下载,称为 MSDNArduinoClient 的Visual Studio2013年项目中的源代码。 图 7 显示了客户端的主屏幕,从中您发送命令到 Arduino 的设备。

The Windows Phone Client Interface
图 7 Windows Phone 客户端界面

创建其他移动设备 (包括 iOS 和 Android) 的类似客户端就不会有困难,因为他们大多数提供图书馆,以生成其他命令使用 HTTP 请求的客户端。 此外,有可能直接与使用传统语言如JAVA、 PHP 或红宝石,简化了此过程的 Windows Azure 服务总线进行交互。 这些 Sdk 开放源代码许可证下发布,可以发现在 github.com/WindowsAzure

总结

建设互联网-­使用 Windows Azure 服务总线管理设备和服务连接的事情的体系结构提供了简易的安全,规模和地址的客户端 individ­ually 而不会导致昂贵的 VPN 解决方案,高效地处理偶尔的效益与断开连接的情况。 作为专用邮箱交换设备和服务之间的消息的队列行为,支持不同的通信使用案例和常见的字段中的模式。 Windows Azure 为部署量很高的相互连接的传感器和仪表所需的服务提供可靠、 地理分布和强健的基础设施 — — 一种将继续在未来几年增长的趋势。

Bruno Terkaly是 Microsoft 的开发推广人员。他的知识深度来源于多年来相关领域以及使用大量平台、语言、框架、SDK、库和 API 编写代码的经验。他不辞辛苦,就有关构建基于云的应用程序(特别是使用 Windows Azure 平台)编写代码、发布博客并给予现场演示。您可以阅读他的博客 blogs.msdn.com/b/brunoterkaly

Ricardo Villalobos 是具有超过 15 年的经验设计和创建应用程序的公司在多个行业的经验丰富的软件设计师。他从达拉斯大学工商管理持有不同的技术认证,以及硕士学位,为微软,帮助世界各地的公司要在 Windows Azure 实施解决方案作为一个云建筑师在 DPE 全球范围内参与合作伙伴团队工作。您可以阅读他的博客在 blog.ricardovillalobos.com

Terkaly 和比利亚洛沃斯共同提出大行业会议。 他们鼓励读者的 Windows Azure 内幕交易与他们联系的可用性。 也可以拨打 Terkaly bterkaly@microsoft.com 和比利亚洛沃斯也可以拨打 Ricardo.Villalobos@microsoft.com

衷心感谢以下 Microsoft 技术专家对本文的审阅:阿彼锡拉尔和Clemens Vasters