Думаю, что рано или поздно каждый разработчик программного обеспечения сталкивается с проблемой создания надежной системы передачи сообщений, гарантирующей доставку. Задача, особенно с учетом перспектив развития, оказывается совсем не такой тривиальной, как может показаться на первый взгляд. Разработчики семейства операционных систем Microsoft Windows 9x/Me/CE/NT/2000, как всегда, не бросили пользователей и программистов на произвол судьбы. Механизм Microsoft Message Queue (MSMQ) с блеском решает различные проблемы, связанные с передачей сообщений любых форматов как внутри локальных сетей, так и по Internet. На самом деле MSMQ - весьма мощное средство, поддерживающее и механизм транзакций, и тесную интеграцию с COM+, но в данной статье эти возможности MSMQ рассматриваться не будут. Мы обсудим лишь API, служащие непосредственно для передачи данных, а также несколько недокументированных приемов работы с ними.

Несколько слов об архитектуре MSMQ

В самом общем виде MSMQ - это технология, благодаря которой компьютеры, работающие в гетерогенной сетевой среде, могут обмениваться сообщениями в разное время (асинхронно), возможно, не всегда даже будучи подключенными к сети. До появления MSMQ программирование механизмов асинхронного обмена сообщениями было более чем затруднительным. Другие высокоуровневые механизмы, поддерживаемые инфраструктурой сетей Microsoft, RPC (DCOM), обеспечивали лишь синхронное взаимодействие между компонентами распределенных систем. Решить эту задачу, разрабатывая собственный механизм, на базе sockets я не мог в течение трех лет.

В основе MSMQ лежат два понятия - очереди (queue) и сообщения (message). Сообщение суть логическое объединение некоторого набора свойств. Очередь представляет собой виртуальную таблицу, полями которой являются свойства сообщений, а строками, соответственно, сообщения. Это позволяет организовать доступ к MSMQ через ADO, но пока данный механизм мы рассматривать не будем. Физически очередь сообщений представляет собой особым образом устроенный файл, хранящийся в папке, имя которой содержится в параметре реестра Msmq-RootPath, в разделе HKEY_LOCAL_MACHINESOFTWARE MicrosoftMSMQParameters. Следовательно, механизмы ограничения доступа к очередям ничем не отличаются от обычных механизмов системы безопасности Windows 2000. Но, кроме того, механизм MSMQ предусматривает защиту отдельных сообщений средствами криптозащиты (шифрования и электронной подписи) и поддерживает инфраструктуру открытых ключей.

Экран 1. Демонстрационная программа работы с MSMQ.

На Экране 1 показан интерфейс программы, которую я буду использовать в качестве демонстрационной. Исходные тексты программы можно найти по адресу: http://www.members.xoom.com/alex_ep/ mqexplorer/mqsrc.zip. Это упрощенный вариант MSMQ-навигатора. Программа отличается от входящей в поставку MMC оснастки тем, что позволяет работать с удаленными компьютерами. Это достигается за счет использования недокументированной части библиотеки MQRT.DLL, служащей для управления функциями MQ. Но давайте обо всем по порядку.

Установка необходимого программного обеспечения

Для того чтобы приведенные в тексте примеры работали, придется кое-какие программы установить, а кое-какие настроить. Для работы с публичными очередями необходимо установить и настроить сервер MSMQ, который входит в стандартную поставку Windows 2000 Server. Подробнее об этом рассказано в статье http://support.microsoft.com/support/ kb/articles/Q256/0/96.ASP.

На клиентском компьютере также необходимо установить клиента MSMQ.

Это делается следующим образом:

  1. в Control Panel требуется выбрать модуль Add/Remove Program;
  2. далее следует выбрать значок Com-ponents;
  3. в появившемся списке нужно отметить Microsoft Message Queues и ответить на несколько простых вопросов.

После этого установку клиента MSMQ можно считать законченной.

Работаем с MSMQ

Перед тем как рассмотреть ряд примеров, заметим, что во всех фрагментах кода используются две функции AnsiToUnicode и UnicodeToAnsi, преобразующие строку символов ANSI в Unicode и наоборот. В этих функциях используются вызовы Win32-функций MultiByteToWideChar и для обратного преобразования WideCharToMultiByte. Пример можно найти в коде демонстрационной программы.

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

Начнем с более простых примеров.

Получение списка компьютеров в домене. В состав библиотеки NetAPI входит функция NetServerEnum, позволяющая легко решить эту задачу. Ее подробное описание можно найти по адресу: http://msdn.microsoft.com/library/de-fault.asp?url=/library/enus/ netmgmt/hh/network/ntlmapi2_1vl9.asp, здесь же я привожу пример использования данной функции (см. Листинг 1).

Функция NetServerEnum весьма удобна. Для получения результата не надо создавать буфер - это делает операционная система. Но полученный после вызова функции буфер необходимо освободить вызовом функции Net-BufferFree. Замечу, что этот механизм используется практически всеми функциями NetAPI.

Теперь для каждого компьютера из списка необходимо получить списки очередей сообщений - частных и публичных. Следующие два раздела посвящены именно этой задаче.

Получение списка публичных очередей на хосте. Теперь мы переходим к программным интерфейсам, которым и посвящена статья. Как я уже отмечал, очереди могут быть публичными или частными. Механизмы получения списков для публичных и частных очередей совершенно разные. Для первых все достаточно просто.

Скелет функции, которая выполняет задачу получения списка публичных очередей для хоста, приведен в Листинге 2. Отметим, что предназначенные для этой цели функции MQLo-cateBegin и MQLocateNext возвращают ВСЕ публичные очереди в домене. Следовательно, имя каждой очереди должно быть проанализировано, из него должно быть вычленено имя компьютера и т. д. В примере это делается приблизительно, т. е. если имя очереди начинается с последовательности символов, соответствующей передаваемому в качестве параметра имени сервера, то считается, что проверка пройдена. Очевидно, что для очереди test1/test_queue и компьютера test будет получен неправильный результат.

Получение списка частных очередей на хосте. С частными очередями тоже все весьма несложно, но в документации в поставке ни MSDN, ни Platform SDK на эту тему нет. Тем не менее на сайте Microsoft (http://support.microsoft.com/support/ kb/articles/Q242/4/71.ASP) можно найти описание интерфейса MQ Local Admin, содержащего необходимые функции. В Листинге 3 показано, как решается эта задача.

Теперь, когда мы умеем узнавать все о структуре очередей сообщений на компьютере, остается понять, как осуществляется отправка сообщения в очередь и получение сообщения из очереди.

Отправка сообщения в очередь. Это задача вполне заурядная. Она прекрасно описана в MSDN. В Листинге 4 приведен пример кода, реализующего отправку сообщения в очередь.

В коде используется функция Open-Queue. В ней инкапсулирован механизм открытия очереди сообщений для того или иного действия. Текст функции приведен в Листинге 5.

Получение списка сообщений из очереди. И, наконец, последняя из рассматриваемых в этой статье задач. Нам осталось научиться читать сообщения, помещенные в очередь. В Листинге 6 показано, как это сделать.

Заключение

Механизмы MSMQ весьма разнообразны. Компания Microsoft поставляет COM-компонент, инкапсулирующий все описанные здесь и многие другие клиентские функции, предоставляя к ним высокоуровневый, комфортный интерфейс. Лишь функции библиотеки администрирования реализованы на низком уровне. Но это пока. MSMQ хорошо интегрирован с COM+, а начиная с версии 3.0, которая входит в Windows XP, этот механизм имеет поддержку SOAP, что позволяет задействовать HTTP в качестве транспорта для MSMQ. С другой стороны, многие независимые разработчики предлагают решения, основанные на механизме MSMQ. Например, специалисты компании Info Industries Group разработали механизм передачи SOAP-запросов через MSQM, не требующий наличия Microsoft IIS.

Так что MSMQ представляет собой действительно мощнейший инструмент для построения асинхронных распределенных систем, работающих в режиме реального времени. В будущих статьях мы, без сомнения, еще не раз коснемся этой темы.

Александр Эпштейн - руководитель отдела разработки компании Internet Investment Group. С ним ножно связаться по адресу: alex_ep@hotmail.com.