|
Автор статьи: Глеб Уфимцев Погружение в проблематику Достаточно нередко у разработчиков клиент-серверных приложений возникает необходимость организовать некий механизм, позволяющий по событию на SQL-сервере уведомить того или иного клиента. Ещё чаще это является розово-голубой мечтой заказчика, чтобы разработчик реализовал такой механизм. Например, при превышении лимитов отгрузки какому-либо потребителю, должны быть немедленно уведомлены менеджеры, работающие с этим потребителем. Некоторые заказчики систем требуют (а мечтают об этом все заказчики без исключения), чтобы при изменении каких-то данных, у остальных пользователей системы эта информация автоматически обновлялась, причем незамедлительно. Здесь не будет обсуждаться целесообразность такого требования (оно имеет много оснований для критики), здесь будут обсуждаться только пути решения. Microsoft SQL-сервер имеет штатное средство для организаций уведомлений - alerts, но это средство имеет весьма ограниченное применение, по большому счету не дающее возможность создать на его основе гарантированно работающий механизм. И вот почему: Связь с клиентской программой может быть осуществлена путем посылки e-mail или эмуляцией посылки "net send". И то, и другое неудобно для получения уведомления. Средство e-mail неудобно по причинам: a) нет гарантии доставки, почта может теряться. Посылка путем "net send" неудобна по следующим причинам: a) нет гарантии доставки, так как это организовано через
средство mailslot, не имеющее такой гарантии. И в целом средство alerts неудобно необходимостью регистрации каждого клиента в качестве оператора и соответствующей настройкой. Т.е. для простейших случаев alerts применить можно. Но для большинства случаев оно неприменимо. Известные реализации и концепции Широкой общественности известны несколько вариантов реализации механизма уведомления сервером клиента. Это: 1. Создание объекта (Extended Stored Procedure или
ActiveX), посредством которого SQL-сервер уведомляет клиента
через сокеты TCP/IP. При этом на клиенте организована
прослушка, т.е. клиентская программа стала сервером
TCP/IP. 2. Создание объекта (Extended Stored Procedure или
ActiveX), посредством которого SQL-сервер уведомляет клиента
через named pipes или mailslots. При этом на клиенте
организована прослушка того или другого. 3. Периодический опрос SQL-сервера клиентом (периодическое чтение специальной таблички евентов). Это очень простой путь, но, тем не менее, свободный от большинства вышеперечисленных недостатков. К сожалению, этот метод имеет свои специфичные 2 недостатка: a) получение уведомления может быть задержано на величину таймаута опроса и b) при маленьком таймауте возникает существенный трафик. Тем не менее, при небольшом кол-ве сессий, этот метод вполне пригоден и незаслуженно обойден вниманием. Предлагаемый вариант решения Вашему вниманию предлагается вариант решения проблемы,
свободный от вышеперечисленных (всех вышеперечисленных!)
проблем, но вместе с тем достаточно простой. Идея такова: на
сервер помещается некий двоичный объект, который sql-сервер
может вызывать (а это может быть только Extended Stored
Procedure или ActiveX-объект), имеющий два невзаимосвязанных
метода. Готовое решение Решение состоит из ActiveX-объекта в виде файла AlgoEvt.dll и двух хранимых процедур spWaitForEvent и spRaiseEvent. Перед использованием этот файл надо поместить на сервер и зарегистрировать ActiveX-объект с помощью системной утилиты regsvr32.exe. Дальше вся работа будет производиться через хранимые процедуры. В готовом решении реализована несколько бОльшая функциональность, чем в описанной концепции. Кроме самого факта события, можно передать также произвольную информацию в виде строки в размере до 250 символов. Каждая процедура имеет два параметра. Первая - это уникальный идентификатор-адрес, о котором говорилось выше, а второй параметр - дополнительная передающаяся информация. spWaitForEvent надо вызвать с клиента из отдельного потока (приоритет потока можно выбрать самый низкий). При получении события, процедуру надо перезапустить. Тайм-аут исполнения запроса надо задать бесконечный. Решение здесь: SQLEventsService.zip Преимущества решения 1. Независимость от сетевого протокола и настроек сети. Был
бы коннект к sql-серверу. |
Редакция: Александра Гладченко 2002г. |