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


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

CyberNanny: удаленный доступ через распределенные компоненты

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

Эта статья о приложении под названием CyberNanny, которое я недавно создал, чтобы видеть свою дочку, Миранду, из любого места в любое время. Приложение написано на Visual C++ (MFC) и объединяет в себе такие разные технологии, как Kinect и его SDK, Windows Azure, веб-сервисы и автоматизация Office через Outlook. Проект размещен на CodePlex (cybernanny.codeplex.com), где можно посмотреть его код или внести в него свой вклад.

Прежде чем рассказать об основных элементах этого приложения, я кратко поясню технологии, использованные для его создания.

C++ был — и остается — рабочей лошадкой во многих компаниях, разрабатывающих ПО. Стандарт C++ 11 выводит этот язык на новый уровень. Его можно описать тремя прилагательными: современный, элегантный и крайне быстрый. Кроме того, MFC все еще используется, и Microsoft обновляет ее при каждом выпуске очередной версии своего компилятора Visual C++.

Технология Kinect великолепна, если не сказать больше; она меняет то, как мы взаимодействуем с играми и компьютерами. А благодаря тому, что Microsoft снабдила разработчиков Kinect SDK, перед ними открылся мир новых возможностей в создании приложений, требующих взаимодействия с человеком. Любопытно, что Kinect SDK основан на COM (равно как и новая модель программирования в Windows 8, названная Windows Runtime и часто сокращаемая до WinRT). Этот SDK также доступен в языках Microsoft .NET Framework.

Одно из требований к CyberNanny заключалось в надежной доставке сообщений через очередь с высокой доступностью, и Windows Azure реализует это требование.

Windows Azure — это предложение Microsoft Platform as a Service (PaaS), которое существует уже несколько лет. Эта платформа предоставляет множество сервисов, позволяющих создавать решения поверх них (например, Compute и Storage). Одно из требований к CyberNanny заключалось в надежной доставке сообщений через очередь с высокой доступностью, и Windows Azure реализует это требование.

Использование веб-сервисов из неуправляемого кода возможно через Windows Web Services API (WWSAPI), введенный в Windows 7. У меня есть публикация в блоге (bit.ly/LiygQY), где я описал WPF-приложение, реализующее неуправляемый компонент, который использует WWSAPI. Важно упомянуть, что WWSAPI встроен в ОС, поэтому нет нужды что-либо скачивать или устанавливать, кроме Windows SDK (чтобы получить заголовочные и lib-файлы).

Зачем заново изобретать колесо? Одним из требований к CyberNanny была возможность отправлять сообщения по электронной почте с прикрепленными картинками, поэтому, чтобы не писать собственный класс для обработки электронной почты, я предпочел для этой задачи задействовать функциональность Outlook. Это позволило мне сосредоточиться на главной цели: создании распределенного приложения для присмотра за моей дочкой.

Эта статья состоит из четырех главных разделов:

  • обзор общей архитектуры решения;
  • архитектура Kinect;
  • локально развертываемые компоненты (неуправляемые);
  • размещаемые в облаке компоненты (управляемые).

Обзор общей архитектуры решения

Концепция CyberNanny проста (рис. 1), но в ней есть некоторые движущиеся части. Ее можно кратко описать как толстый клиент, написанный на Visual C++, который захватывает кадры через датчик Kinect. Эти кадры потом можно использовать как снимок, прикрепляемый к новому сообщению электронной почты, формируемому в Outlook через механизм автоматизации. Приложение уведомляется о необработанных запросах следующим образом: по таймеру порождается новый поток, который опрашивает очередь, размещенную в Windows Azure. Запросы ставятся в очередь через веб-страницу ASP.NET.

*
Рис. 1. Архитектура CyberNanny

Kinect for Xbox 360Kinect for Xbox 360
Capture FramesЗахват кадров
Polling QueueОпрос очереди
Windows Azure Web Role (2 Cores) WCF Service QueueWindows Azure
Веб-роль (2 узла)
Очередь WCF-сервиса
SmartphoneСмартфон
RequestЗапрос
TabletПланшет
Happy DadСчастливый папочка
LaptopЛэптоп
Windows 7 LaptopЛэптоп с Windows 7
If there's a request, take picture, compose e-mail, attach picture and sendЕсли есть запрос, делаем снимок, формируем почтовое сообщение, прикрепляем снимок и отправляем
Send an E-mailОтправка электронной почты


Для запуска и тестирования этого решения у вас должны быть:

  • датчик Kinect (я использовал версию для Xbox 360);
  • подписка Windows Azure;
  • Kinect SDK.

Архитектура Kinect

Хорошее понимание того, как устроены вещи и как их можно реализовать, крайне важно в любом проекте разработки, и случай с Kinect — не исключение. Microsoft предоставила SDK для разработчиков, использующих как управляемый, так и неуправляемый код. Я опишу архитектуру Kinect, показанную на рис. 2.

*
Рис. 2. Архитектура Kinect for Windows

ApplicationsПриложения
NUI APINUI API
Windows Core Audio and Speech APIsWindows Core Audio API и Speech API
DMO Codec for Mic ArrayDMO-кодек для микрофонной решетки
Device SetupНастройка устройства
Device  AccessДоступ к устройству
Video Stream ControlУправление видеопотоком
Audio Stream ControlУправление аудиопотоком
User ModeПользовательский режим
WinUSB Device StackСтек устройств WinUSB
WinUSB Camera StackСтек камер WinUSB
USBAudio Audio StackСтек аудиоустройств USBAudio
Kernel ModeРежим ядра
Kernel-Mode Drivers for Kinect for WindowsДрайверы режима ядра для Kinect for Windows
USB HubUSB-концентратор
HardwareАппаратный уровень
MotorМотор
CamerasКамеры
Audio Mic ArrayМикрофонная решетка
Kinect SensorДатчик Kinect
Kinect for Windows SDKKinect for Windows SDK
Windows ComponentsWindows-компоненты
User-Created ComponentsКомпоненты, создаваемые пользователем


Цифры в кружках на рис. 2 соответствуют следующему.

  1. Аппаратная часть Kinect Аппаратный компоненты, включая Kinect и USB-концентратор, через который этот датчик подключается к компьютеру.
  2. Драйверы Kinect Windows-драйверы для Kinect, устанавливаемые в процессе установки SDK, как описывается в этой статье. Драйверы Kinect поддерживают:
    • микрофонную решетку (microphone array) Kinect как аудиоустройство режима ядра, к которому можно обращаться через стандартные аудио-API в Windows;
    • управление потоковыми аудио и видео (цвет, глубина и скелет);
    • функции перечисления устройств, позволяющие приложению использовать более одного датчика Kinect.

    Хорошее понимание того, как устроены вещи и как их можно реализовать, крайне важно в любом проекте разработки, и случай с Kinect — не исключение.

  3. Аудио- и видеокомпоненты Kinect Natural User Interface (NUI) для отслеживания скелета, аудио, цвета и глубины изображения.
  4. DirectX Media Object (DMO) Необходим для формирования диаграммы направленности микрофонной решетки и локализации источника звука.
  5. Стандартные API в Windows 7 API-интерфейсы для звука, речи и медиа в Windows 7, описанные в Windows 7 SDK и Microsoft Speech SDK.

Я продемонстрирую, как я использовал видеокомпонент для захвата кадров, которые потом сохранялись как JPEG-файлы для отправки по электронной почте. Рендеринг захваченных кадров осуществляется средствами Direct2D.

Класс Nui_Core Я написал класс Nui_Core, который инкапсулирует функциональность, нужную мне от датчика Kinect. В приложении создается только один экземпляр этого класса. Приложение взаимодействует с датчиком через член типа INuiSensor, представляющий физическое устройство, подключенное к компьютеру. Важно помнить, что Kinect SDK основан на COM, поэтому вышеупомянутый интерфейс — равно как и все остальные COM-интерфейсы, широко применяемые в этом приложении, — управляются смарт-указателями (например, CComPtr<INuiSensor> m_pSensor;).

Захват кадров с датчика осуществляется следующим образом.

  1. Проверяем, доступен ли датчик; для этого вызываем NuiGetSensorCount.
  2. Создаем экземпляр датчика Kinect вызовом NuiCreateSensorByIndex.
  3. Создаем объект фабрики вызовом D2D1CreateFactory (для создания Direct2D-ресурсов).
  4. Создаем события для каждого потока данных (stream), необходимого приложению.
  5. Открываем потоки данных вызовом NuiImageStreamOpen.
  6. Обрабатываем захваченные данные (кадр).

Подготовив экземпляр Nui_Core, вы можете легко сделать снимок по требованию, вызвав метод TakePicture, показанный на рис. 3.

Рис. 3. Метод TakePicture

void Nui_Core::TakePicture(std::shared_ptr<BYTE>& imageBytes, int& bytesCount) {
  byte *bytes;
  NUI_IMAGE_FRAME imageFrame;
  NUI_LOCKED_RECT LockedRect;
  if (SUCCEEDED(m_pSensor->NuiImageStreamGetNextFrame(m_hVideoStream,
    m_millisecondsToWait, &imageFrame))) {
    auto pTexture = imageFrame.pFrameTexture;
    pTexture->LockRect(0, &LockedRect, NULL, 0);
    if (LockedRect.Pitch != 0) {
      bytes = static_cast<BYTE *>(LockedRect.pBits);
      m_pDrawColor->Draw(bytes, LockedRect.size);
    }
    pTexture->UnlockRect(0);
    imageBytes.reset(new BYTE[LockedRect.size]);
    memcpy(imageBytes.get(), bytes, LockedRect.size);
    bytesCount = LockedRect.size;
    m_pSensor->NuiImageStreamReleaseFrame(m_hVideoStream, &imageFrame);
  }
}

Заметьте, что вы передаете смарт-указатель, чтобы сохранить байты изображения и количество байтов, скопированных в него, а затем эта информация используется для создания битовой карты.

Не забывайте по окончании работы с датчиком выключать его вызовом NuiShutdown; кроме того, нужно освобождать описатели, использовавшиеся вами.

Класс DrawDevice Как упоминалось ранее, средства рендеринга предоставляются Direct2D; вот почему для использования Nui_Core требуется другой вспомогательный класс. Этот класс отвечает за обеспечение доступности ресурсов для захваченного кадра, в данном случае — битовой карты.

Три основных метода класса DrawDevice: Initialize, Draw и EnsureResources. Я опишу каждый из них.

Initialize Отвечает за настройку трех членов типа DrawDevice. В приложении имеется элемент управления «вкладки» с тремя вкладками, поэтому для каждой из них предусмотрен свой член (определяют режимы просмотра Color, Skeletal и Depth). Каждая вкладка — это окно, в котором визуализируется соответствующий кадр. InitializeColorView, показанный в следующем коде, — хороший пример вызова метода Initialize:

bool Nui_Core::InitializeColorView() {
  auto width = m_rect.Width();
  auto height = m_rect.Height();
  m_pDrawColor = std::shared_ptr<DrawDevice>(new DrawDevice());
  return (m_pDrawColor.get()->Initialize(m_views[TAB_VIEW_1]->m_hWnd,
  m_pD2DFactory.p, 640, 320, NULL));
}

Draw Визуализирует кадр на соответствующей вкладке. Принимает аргумент типа Byte*, захваченный датчиком. Как и в видеороликах, эффект анимации достигается последовательной визуализацией статических кадров.

EnsureResources Отвечает за создание битовой карты по запросу метода Draw.

Локально развертываемые компоненты (неуправляемые)

Проект CyberNanny состоит из следующих компонентов.

  • Приложение:
    • CCyberNannyApp (наследуется от CWinApp). В приложении один член типа Nui_Core для взаимодействия с датчиком.
  • UI-элементы:
    • CCyberNannyDlg (основное окно, наследуется от CDialogEx);
    • CAboutDlg (диалог About, наследуется от CDialogEx).
  • Клиент веб-сервиса:
    • файлы, автоматически генерируемые после выполнения WSUTIL применительно к сервису, имеют формат Web Services Description Language (WSDL). Эти файлы содержат сообщения, структуры и методы, предоставляемые веб-сервисом на основе WCF.
  • Объекты Outlook:
    • чтобы манипулировать какими-либо объектами Outlook, вы должны импортировать их в свой проект, выбрав Add MFC Class в окне ActiveX Control Wizard. Объекты, используемые в этом приложении, — Application, Attachment, Mail-Item и Namespace.
  • Прокси:
    • это собственный класс, который инкапсулирует процедуру создания объектов, нужных для взаимодействия с WWSAPI.
  • Вспомогательные классы:
    • используются для поддержки такой функциональности приложения, как преобразование битовой карты в JPEG для уменьшения размера файла, предоставление оболочки для отправки сообщений по электронной почте и взаимодействия с Outlook и др.

При запуске приложения происходят следующие события.

  1. Вызовом RegisterWindowMessage определяется новое оконное сообщение. Это необходимо для добавления элементов в список событий при обработке запросов. Дело в том, что вы не можете напрямую модифицировать UI-элементы из любого потока, отличного от UI-потока, — иначе вы получите исключение, связанное с недопустимым вызовом между потоками. Все это управляется MFC-инфраструктурой обработки сообщений.
  2. Вы инициализируете член Nui_Core и настраиваете пару таймеров (один из них обновляет текущее время в строке состояния, а другой запускает поток для опроса очереди, чтобы проверить наличие в ней необработанного запроса).
  3. Датчик Kinect начинает захват кадров, но приложение не получает снимок, если в очереди нет запроса. Метод ProcessRequest отвечает за получение снимка, его сериализацию на диск, запись в средство просмотра событий и запуск механизма автоматизации Outlook, как показано на рис. 4.

Рис. 4. Вызов метода ProcessRequest

void CCyberNannyDlg::ProcessRequest(_request request) {
  if (!request.IsEmpty) {
    auto byteCount = 0;
    ImageFile imageFile;
    std::shared_ptr<BYTE> bytes;
    m_Kinect.TakePicture(bytes, byteCount);
    imageFile.SerializeImage(bytes, byteCount);
    EventLogHelper::LogRequest(request);
    m_emailer.ComposeAndSend(request.EmailRecipient,
    imageFile.ImageFilePath_get());
    imageFile.DeleteFile();
  }
}

Кадр, изначально захваченный Kinect, является битовой картой, которая занимает примерно 1,7 Мб (что неудобно для отправки по почте, а значит, битовую карту нужно конвертировать в JPEG-изображение). Кроме того, она перевернута, поэтому требуется поворот изображения на 180°. С этой целью выполняется пара вызовов GDI+. Эта функциональность инкапсулирована в класс ImageFile.

Класс ImageFile служит оболочкой для операций с GDI+. Два основных метода этого класса представляют собой следующее.

  1. SerializeImage Этот метод принимает shared_ptr<BYTE>, который содержит байты захваченного кадра, подлежащие сериализации в изображение, а также счетчик байтов. Кроме того, изображение поворачивается вызовом метода RotateFlip.
  2. GetEncoderClsid Как упоминалось, файл изображения слишком велик для использования в качестве вложения в почтовом сообщении, поэтому его нужно кодировать в более компактный формат (JPEG, например). GDI+ предоставляет функцию GetImageEncoders, позволяющую выяснить, какие конвертеры доступны в системе.

До сих пор я рассматривал, как приложение использует датчик Kinect и как из захваченных кадров создается картинка, отправляемая по электронной почте. Теперь я покажу, как вызывать WCF-сервис, размещенный в Windows Azure.

Кадр, изначально захваченный Kinect, является битовой картой, которая занимает примерно 1,7 Мб (что неудобно для отправки по почте, а значит, битовую карту нужно конвертировать в JPEG-изображение). Кроме того, она перевернута, поэтому требуется поворот изображения на 180°.

WWSAPI, введенный в Windows 7, позволяет разработчикам, использующим неуправляемый код, легко работать с веб- или WCF-сервисами, не беспокоясь о деталях коммуникационного взаимодействия (сокетах). Первый шаг в использовании сервиса — получение WSDL, который применяется с WSUTIL и в свою очередь генерирует код на C для прокси сервиса, который представляет собой структуры данных, необходимые сервису. Существует альтернатива под названием Casablanca (bit.ly/JLletJ) — она поддерживает клиент-серверное взаимодействие в облаке для неуправляемого кода, но ее не было на момент написания CyberNanny.

Как правило, полученный WSDL сохраняется на диске, а затем WSDL-файл вместе со связанными файлами схемы используется как ввод для WSUTIL. Учитывайте один аспект в работе со схемами. Их нужно скачивать наряду с WSDL, а иначе WSUTIL будет жаловаться в процессе генерации файлов. Определить нужные схемы можно, проверив параметр .xsd в разделе схемы в WSDL-файле:

wsutil /wsdl:cybernanny.wsdl /xsd:cybernanny0.xsd
cybernanny1.xsd cybernanny2.xsd cybernanny3.xsd
/string:WS_STRING

В CyberNanny имеется только веб-роль, которая занимает два узла, чтобы обеспечить высокую доступность.

Конечные файлы можно добавить в решение, а затем вызывать сервис через эти файлы. Для работы с WWSAPI требуются четыре основных объекта:

  1. WS_HEAP;
  2. WS_ERROR;
  3. WS_SERVICE_PROXY;
  4. WS_CHANNEL_PROPERTY.

Эти объекты обеспечивают взаимодействие между клиентом и сервисом. Функциональность вызова сервиса я поместил в класс Proxy.

Большинство WWSAPI-функций возвращает HRESULT, поэтому отладка и устранение ошибок могут оказаться весьма трудной задачей. Но не бойтесь: вы можете включить трассировку из Windows Event Viewer и увидеть точную причину сбоя данной функции. Чтобы включить трассировку, выберите Applications and Services Logs | Microsoft | WebServices | Tracing (щелкните правой кнопкой мыши для ее включения).

Это в основном исчерпывает описание неуправляемых компонентов решения. Более подробную информацию можно извлечь из исходного кода, размещенного на сайте CodePlex. Следующий раздел посвящен последнему компоненту решения — Windows Azure.

Размещаемые в облаке компоненты (управляемые)

Пожалуйста, обратите внимание, что это не учебное пособие по Windows Azure, а просто описание компонентов Windows Azure, применяемых в CyberNanny. За более глубокой и детальной информацией обращайтесь на веб-сайт Windows Azure windowsazure.com. Платформа Windows Azure (рис. 5) включает следующие сервисы:

  • Windows Azure Compute;
  • Windows Azure Storage;
  • Windows Azure SQL Database;
  • Windows Azure AppFabric;
  • Windows Azure Marketplace;
  • Windows Azure Virtual Network.

*
Рис. 5. Сервисы платформы Windows Azure

Cloud ApplicationsОблачные приложения
Web/Worker RolesВеб- и рабочие роли
Business AnalyticsБизнес-аналитика
SQL Azure ReportingОтчетность SQL Azure
NetworkingСетевые сервисы
Traffic Manager ConnectTraffic Manager
Connect
HPCHPC
HPC SchedulerПланировщик HPC
Data ManagementУправление данными
SQL Azure Tables BlobsSQL Azure
Таблицы
Двоичные объекты
MessagingОбмен сообщениями
Queues Service BusОчереди
Шина сервисов
CachingКеширование
In-Memory CDNВ памяти
CDN
CommerceКоммерция
MarketplaceMarketplace
IdentityИдентификация
Windows Azure Active DirectoryWindows Azure Active Directory
Visual StudioVisual Studio
EclipseEclipse
.NET.NET
JavaJava
PHPPHP
Node.jsNode.js
SDKsSDK


В CyberNanny имеется только веб-роль, которая занимает два узла, чтобы обеспечить высокую доступность. Если один из узлов выйдет из строя, платформа переключится на работоспособный узел. Веб-роль — это приложение ASP.NET, и оно лишь вставляет элементы сообщений в очередь. Эти сообщения потом поступают от CyberNanny. Кроме того, имеется WCF-сервис, который является частью веб-роли, отвечающей за обработку очереди.

Заметьте, что роль в Windows Azure — это индивидуальный компонент, выполняемый в облаке, где каждый экземпляр облака соответствует экземпляру виртуальной машины (VM). В случае CyberNanny я использую две VM.

В CyberNanny имеется веб-роль, представляющая собой веб-приложение (не важно, состоит оно только из ASPX-страниц или является набором WCF-сервисов), которое выполняется в IIS. Она доступна через конечные точки HTTP/HTTPS. Существует и другой тип роли — рабочая (Worker Role). Это приложение фоновой обработки (например, для финансовых расчетов), и оно способно предоставлять внешние (доступные из Интернета) и внутренние конечные точки.

Это приложение также использует очередь, предоставляемую Windows Azure Storage, которое обеспечивает надежное хранение и доставку сообщений. Изящество этой очереди в том, что вам не приходится писать никакого специализированного кода для ее использования. От вас не требуется и структуризации хранилища данных так, чтобы оно напоминало очередь, потому что вся эта функциональность обеспечивается самой платформой.

Помимо высокой доступности и масштабируемости, еще одно преимущество платформы Windows Azure — унификация в выполнении разнообразных процессов, например разработки, тестирования и развертывания решений на основе Windows Azure из Visual Studio, а также применение .NET в качестве общепринятого языка при построении решений.

Это приложение также использует очередь, предоставляемую Windows Azure Storage, которое обеспечивает надежное хранение и доставку сообщений.

Есть и некоторые другие интересные функции, которые я хотел бы добавить в CyberNanny, например обнаружение движения и распознавание речи. Если вы хотите использовать это ПО или внести свой вклад в данный проект, пожалуйста, не стесняйтесь. Задействованные технологии теперь вполне доступны, и, хотя они выглядят «разными», они способны взаимодействовать и отлично сочетаются друг с другом.

Удачи в кодировании!

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


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