Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft Разработка приложений Облако/Azure Microsoft Azure Service Bus и Интернет вещей. Часть 2 RSS

Microsoft Azure Service Bus и Интернет вещей. Часть 2

Текущий рейтинг: 0 (проголосовало 0)
 Посетителей: 479 | Просмотров: 584 (сегодня 0)  Шрифт: - +

В прошлой статье (http://www.oszone.net/24591/) мы обсудили текущий технологический ландшафт в сфере межмашинных (machine-to-machine, M2M) вычислений. Такие вычисления относятся к технологиям, которые соединяют устройства между собой (обычно для промышленных систем контроля и управления) в виде датчиков или контрольно-измерительных приборов. Распространение недорогих и простых в программировании крошечных компьютеров привело к расширению этой концепции в то, что теперь называют Интернетом вещей (Internet-of-Things, IoT), сделав возможными сценарии, где даже обыкновенную бытовую технику можно контролировать или использовать в качестве источников информации для генерации событий. Благодаря этому нетрудно посылать оповещения, когда нужно пополнить холодильник, автоматически закрыть оконные жалюзи на ночь или отрегулировать температуру в соответствии с привычками конкретной семьи.

Мы также рассмотрели пример использования Microsoft Azure Service Bus для соединения устройств как альтернативу применению VPN, когда нужно решать проблемы адресации, защиты и производительности, связанные с развертыванием большого количества датчиков или контрольно-измерительных приборов (КИП). Это становится все важнее, учитывая, что, согласно новейшему отчету «BI Intelligence» от Business Insider, к 2018 году в мире будет насчитываться более девяти миллиардов соединений, прямо относящихся к IoT (read.bi/18L5cg8).

Используя выделенную очередь Service Bus или Topic для какого-либо устройства, можно обеспечить элегантный способ, позволяющий добиться отказоустойчивости в условиях непостоянства подключений для приложений IoT. В данной статье мы подробно рассмотрим практическую реализацию на основе Microsoft Azure, которая иллюстрирует эти концепции, и разработаем проект Service Bus с очередями устройств, применяя рабочую роль для прослушивания этих очередей в Cloud Services, и запрограммируем устройство Arduino, которое будет выполнять команды, удаленно посылаемые мобильными клиентами, как показано на рис. 1.

*
Увеличить

Рис. 1. Архитектура IoT с применением Microsoft Azure Service Bus

Mobile and Desktop DevicesМобильные и настольные устройства
REST Interface/SDKsREST-интерфейс/SDK
Microsoft Azure Service BusMicrosoft Azure Service Bus
Microsoft Azure Cloud ServiceОблачный сервис Microsoft Azure
TCP ConnectionTCP-соединение
ArduinoArduino

Если посмотреть на эту схему, то становится очевидным, что компонент Microsoft Azure Service Bus является центральной частью проекта, обеспечивая аутентификацию, распространение сообщений и масштабируемость для поддержки множества устройств, которые будут отправлять данные или принимать удаленные команды. Service Bus доступна во всех информационных центрах Microsoft, которые предлагают сервисы Microsoft Azure, и поддерживается инфраструктурой хранилищ с высокой степенью избыточности. Кроме того, как и остальные компоненты Microsoft Azure, она предоставляет открытый и простой в понимании REST-интерфейс наряду с несколькими SDK (Microsoft .NET Framework, Java, PHP, Ruby и др.), опирающимися на этот интерфейс.

В предлагаемой нами архитектуре устройства «общаются» с .NET-приложением, выполняемым в Microsoft Azure Cloud Services, который действует как шлюз к Service Bus. Это упрощает процесс взаимодействия приложения с назначенной ему очередью. Такой подход обеспечивает полную поддержку любого из четырех шаблонов коммуникации IoT, описанных в нашей предыдущей статье: Telemetry, Inquiry, Command и Notification. Здесь мы реализуем сценарий, в котором мобильное устройство посылает команду другому устройству, чтобы выполнить некое действие; в данном случае включить или выключить LED-индикатор. Одно из преимуществ этого решения в том, что, если устройство временно отсоединено от сети, оно сможет получить команды, как только соединение с Интернетом будет возобновлено. Кроме того, в сообщении можно указать срок его действия, чтобы избежать выполнения задачи в неподходящий момент, или запланировать отправку сообщений в определенное время в будущем.

Для этого примера мы используем хорошо известное и подробно документированное устройство Arduino, о котором мы говорили в прошлой статье. Для подтверждения концепции в части мобильного клиента мы создадим приложение Windows Phone.

Вот наш простой сценарий.

  1. При запуске устройство Arduino посылает идентификационный сигнал шлюзовому приложению, выполняемому в Microsoft Azure Cloud Services. Шлюз создает очередь Service Bus для этого устройства, если таковой еще нет, и устанавливает TCP-соединение, готовое к отправке команд.
  2. Приложение Windows Phone посылает команду в очередь Microsoft Azure Service Bus, назначенную устройству.
  3. Сообщение остается в очереди, пока шлюзовое приложение не извлечет его и не отправит команду устройству Arduino по установленному TCP-соединению.
  4. Устройство Arduino включает или выключает LED-индикатор в зависимости от команды.

Рассмотрим этапы, которые делают возможными перечисленные выше операции.

Этап 1: создание пространства имен Microsoft Azure Service Bus Используя свои удостоверения Microsoft Azure (вы можете запросить пробную учетную запись по ссылке bit.ly/1atsgSa), войдите на веб-портал и выберите раздел SERVICE BUS (рис. 2). Выберите вариант CREATE и введите имя для вашего пространства имен. Затем щелкните CONNECTION INFORMATION и скопируйте текст в поле Connection String, которое потребуется вам позже.

*
Рис. 2. Создание пространства имен Microsoft Azure Service Bus

Этап 2: создание шлюзового приложения и его развертывание в Microsoft Azure Cloud Services Код для шлюзового приложения, которое извлекает сообщения из очереди Service Bus и ретранслирует команды устройству Arduino, включен в пакет исходного кода к этой статье (доступен по ссылке msdn.microsoft.com/magazine/msdnmag0314). Он основан на разработках Клеменса Вастерса (Clemens Vasters), который любезно поделился ими для этой статьи. Его исходный проект можно найти по ссылке bit.ly/L0uK0v.

Прежде чем углубиться в этот код, убедитесь, что у вас установлена Visual Studio 2013 наряду с версией 2.2 пакета Microsoft Azure SDK for .NET (bit.ly/JYXx5n). Решение включает три проекта:

  • ArduinoListener — содержит основной код WorkerRole;
  • ConsoleListener — консольная версия ArduinoListener для локального тестирования;
  • MSDNArduinoListener — проект развертывания ArduinoListener в Microsoft Azure.

Если вы изучите файлы ServiceConfiguration.cscfg (для облачного и локального развертывания) в проекте MSDNArduinoListener, то заметите параметр, в котором хранится строка подключения для Service Bus. Замените его значение тем, что вы получили на этапе 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). Далее приемник очереди устройства (device queue receiver) настраивается на асинхронный режим для извлечения сообщений (команд) из очереди. В этой очереди будут храниться команды, отправленные мобильными устройствами, такими как 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» или «OFF», в поток соединения, установленного с устройством, записывается соответствующая информация (рис. 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.CompleteAsync), пока операция записи в поток соединения с устройством не будет успешной. Кроме того, чтобы поддерживать соединение в активном состоянии, ожидается, что устройство будет периодически посылать команду ping для проверки связи (ping heartbeat). В этом прототипе мы не ожидаем подтверждения от устройства при получении сообщения. Однако в производственной системе это было бы обязательным условием для соответствия шаблону Command.

Этап 3: развертывание проекта ArduinoListener в Microsoft Azure Cloud Services Развернуть ArduinoListener в Microsoft Azure крайне просто. В Visual Studio 2013 щелкните правой кнопкой мыши проект MSDNArduinoListener и выберите Publish. Конкретные инструкции по работе с Publish Microsoft Azure Application Wizard вы найдете по ссылке bit.ly/1iP9g2p. По окончании работы мастера вы получите облачный сервис, расположенный в xyz.cloudapp.net. Запишите это имя, так как оно понадобится, когда вы будете создавать клиент Arduino.

Этап 4: программирование устройства Arduino на взаимодействие со шлюзом (слушателем) Устройства Arduino предлагают богатый интерфейс для выполнения сетевых операций, используя простой объект веб-клиента. В нашем прототипе мы решили использовать модель Arduino Uno R3 (bit.ly/18ZlcM8) наряду с соответствующей ей защитой Ethernet (bit.ly/1do6eRD). Для установки, взаимодействия и программирования устройств Arduino в Windows следуйте руководству по ссылке bit.ly/1dNBi9R. В итоге вы получите простую в применении IDE (называемую приложением Arduino), где можно будет писать программы (называемые скетчами) на JavaScript, как показано на рис. 5.

*
Рис. 5. Приложение Arduino

На рис. 6 приведен скетч для взаимодействия с Arduino Listener, созданным на этапе 3 и теперь развернутым в Microsoft Azure.

Рис. 6. Код для устройства Arduino

#include <SPI.h>#include <Ethernet.h>#include <StopWatch.h>
// Введите MAC-адрес и IP-адрес своего контроллера ниже.
// IP-адрес будет зависеть от вашей локальной сети,
// и он не обязателен, если включен DHCP.
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 имеют два основных раздела: setup и loop. Инструкции в разделе setup выполняются только раз; именно здесь происходит инициализация переменных и установление соединений. В нашем примере определяются Ethernet-клиент и связанные значения, устанавливается последовательное соединение (для целей отладки), а затем разъем (pin), к которому подключен LED-индикатор, инициализируется как порт вывода.

Код в разделе loop выполняется постоянно и включает два основных блока на основе состояния TCP-соединения между устройством Arduino и слушателем, работающим в Microsoft Azure Cloud Services: connected (подключено) или disconnected (отключено). Когда соединение устанавливается впервые, запускается объект stopwatch, который начинает отслеживать время этого соединения. Кроме того, слушателю посылается идентификатор устройства, который используется в качестве имени очереди, где будут храниться сообщения и команды.

Блок кода, обрабатывающий поведение Arduino после установления соединения, отслеживает время, прошедшее с момента создания соединения, и посылает слушателю команду ping каждые 200 000 мс, чтобы поддерживать соединение в активном состоянии в отсутствие принимаемых команд. Этот код также пытается считывать данные от слушателя, помещая их в массив buf, если таковые данные поступили. Если обнаружено значение 1, LED-индикатор включается, а если значение равно 2, LED-индикатор выключается. Объект stopWatch сбрасывается после каждой команды.

Как только скетч загружается в устройство, этот код выполняется контроллером Arduino в бесконечном цикле, пытаясь подключиться к облачному сервису. После подключения он пересылает идентификатор устройства, чтобы облачный сервис знал, с каким устройством он взаимодействует. Затем код начинает считывать входные данные от облачного сервиса, сообщающие устройству включить или выключить LED-индикатор (в данном случае он подключен к цифровому порту 8 на устройстве).

Этап 5: создание клиента Windows Phone для отправки сообщений в очередь устройства Взаимодействие с устройством сводится к простейшей отправке сообщений в очередь устройства. Как упоминалось в начале статьи, Microsoft Azure Service Bus предоставляет REST-интерфейс, который позволяет взаимодействовать с ним из нескольких языков программирования. Поскольку официального SDK для разработчиков под Windows Phone нет, мы воспользовались одним из примеров из сообщества Windows Phone, который показывает, как выполнять аутентификацию и взаимодействовать с Service Bus с помощью HTTP-запросов и объекта WebClient. Соответствующий код тоже включен в пакет исходного кода для этой статьи, а проект Visual Studio 2013 называется MSDNArduinoClient. Основной экран клиента, с которого вы посылаете команды на устройство Arduino, показан на рис. 7.

*
Рис. 7. Интерфейс клиента Windows Phone

Создание подобных клиентов для других мобильных устройств (в том числе под управлением iOS и Android) не составит особого труда, поскольку большинство из них предоставляет библиотеки для генерации REST-команд, используя клиенты HTTP-запросов. Более того, можно напрямую взаимодействовать с Microsoft Azure Service Bus, применяя традиционные языки вроде Java, PHP или Ruby, которые упрощают этот процесс. Эти SDK публикуются по лицензии открытого исходного кода, и вы найдете их по ссылке github.com/WindowsAzure.

Заключение

Создание архитектуры Интернета вещей с применением Microsoft Azure Service Bus для управления соединениями с устройствами и сервисами обеспечивает простой способ защиты, масштабирования и адресации к индивидуальным клиентам без издержек VPN-решений, а также позволяет эффективно обрабатывать ситуации, где постоянно связи нет. Очереди действуют как выделенные почтовые ящики, через которые устройства и сервисы обмениваются сообщениями, поддерживая различные сценарии и шаблоны использования, распространенные в полевых условиях. Microsoft Azure предоставляет надежную, географически распределенную и отказоустойчивую инфраструктуру для развертывания необходимых сервисов с большим количеством подключенных между собой датчиков и контрольно-измерительных приборов — этот тренд будет лишь расти в предстоящие годы.

Автор: Бруно Теркали  •  Иcточник: MSDN Magazine  •  Опубликована: 25.07.2014
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:  


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.