Reverse Ajax: Часть 5. Разработка событийно-управляемых Web-приложений

В этом цикле статей говорится о том, как разработать событийно-управляемое Web-приложение с использованием методов Reverse Ajax. В первой части приведены различные способы реализации связи Reverse Ajax. В части 2 объясняется, как реализовать Reverse Ajax, используя WebSockets, и обсуждаются ограничения для Web-серверов с применением Comet и WebSockets. Часть 3 посвящена трудностям реализации своей собственной системы связи Comet или WebSockets и знакомству с Socket.IO. Часть 4 рассказывает об инфраструктурах Atmosphere и CometD. В последней статье этого цикла говорится о разработке событийно-управляемых Web-приложений. Мы создадим пример управляемого событиями Web-приложения, используя прилагаемый исходный код.

Матье Карбу, Java Web-архитектор, Ovea

Фото Матье КарбуМатье Карбу (Mathieu Carbou), Java Web-архитектор и консультант компании Ovea, предоставляет услуги и разрабатывает решения. Он коммиттер и руководитель нескольких проектов по разработке ПО с открытым исходным кодом, докладчик и глава монреальской группы пользователей Java. Матье обладает богатым практическим опытом программирования и специализируется на разработке событийно-управляемых Web-программ для клиентских и серверных систем, а также на решениях для высокомасштабируемых Web-приложений, управляемых событиями и сообщениями. Познакомьтесь с его блогом.



17.08.2012

Введение

В этом цикле статей показано, как разработать событийно-управляемое Web-приложение с использованием методов Reverse Ajax. Часть 1 знакомит читателя с методами Reverse Ajax - опросами, потоками, Comet и ждущим опросом. В части 2 объясняется, как реализовать Reverse Ajax, используя WebSockets, и обсуждаются ограничения для Web-серверов с применением Comet и WebSockets. Часть 3 посвящена трудностям реализации системы связи Comet или WebSockets, если нужна поддержка нескольких серверов или нужно создать независимое Web-приложение, которое пользователи могут разместить на своем сервере. В части 3 также обсуждается Socket.IO. В части 4 говорится об Atmosphere и CometD - самых популярных библиотеках Reverse Ajax с открытым исходным кодом для Java-серверов.

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

Загрузите исходный код примеров для этой статьи.

Предварительные требования

Чтобы извлечь максимальную пользу из этой статьи, в идеале нужно знать JavaScript и Java и иметь некоторый опыт web-разработки. Для запуска примера из этой статьи понадобится также последняя версия Maven и JDK (см. раздел Ресурсы).


Термины

Вы, по-видимому, знакомы с событийно-управляемой архитектурой (EDA), системами EventBus, системами обмена сообщениями, обработкой сложных событий (CEP) и каналами. Эти термины и понятия существуют на протяжении многих лет. Вероятно, по мере развития технологии вы будете встречать их все чаще. В этом разделе приводится краткое описание этих понятий.

Событие
Нечто происходящее в системе. Обычно имеет атрибуты, такие как дата возникновения (метка времени), источник или место (компонент, на котором мы щелкаем кнопкой мыши) и некоторые данные, описывающие само событие. В зависимости от системы событие может содержать и другие атрибуты.
Архитектура обработки событий (EDA)
Другое название - программирование на основе событий; способ разработки, когда приложение состоит из компонентов, которые сообщаются и исполняются путем отправки и приема событий. Примером EDA служит графический интерфейс пользователя Java Swing. Каждый компонент Swing может следить за событиями, реагировать на них, отправлять другие события и т.п. EDA состоит из нескольких частей: источников событий, потребителей событий, событий и программного обеспечения обработки событий.
  • Источник событий - это компонент, который инициирует события. В примере из этой статьи источником событий служит кнопка отправки формы.
  • Потребитель событий - это компонент, который отслеживает определенные события. Например, в случае отправки формы браузер отслеживает события нажатия кнопок отправки данных формы на сервер.
  • Событийно-управляемое программное обеспечение - система, в которой источники событий публикуют события, а потребители регистрируются на их получение. В зависимости от программного обеспечения обработка может быть простой (только пересылка полученных событий потребителю) или сложной (CEP). В случае CEP программное обеспечение поддерживает различные средства обработки, такие как агрегирование, фильтрация и преобразование событий.

    Примером такого программного обеспечения служит Esper. Событийно-управляемое программное обеспечение - это не обязательно автономное приложение; это может быть библиотека, встроенная в разрабатываемое приложение.

Системы передачи сообщений
Событийно-управляемые приложения, в которых источники событий публикуют сообщения в каналы, а потребители подписываются на эти каналы. Источники и потребители событий не поддерживают никакой связи друг с другом и являются полностью независимыми. В событийно-управляемых приложениях этого типа вместо термина событие часто применяется термин сообщение.
Каналы
Способ классификации событий в системе обмена сообщениями. Представляют собой пункты назначения, куда источники событий хотят направлять свои события. Например, в приложении чат-рума каналом будет /chatapplication/chatrooms/asdrt678. Этот канал определяет конкретный чат-рум, куда источники событий могут отправлять сообщения и на который графический компонент должен подписаться, чтобы отображать поступающие сообщения.

В некоторых системах обмена сообщениями есть два типа каналов: очереди и темы.

  • Очередь - сообщение ставится в очередь, и только один потребитель событий может принять и обработать его. Другие потребители его не увидят. Очереди могут быть постоянными, чтобы гарантировать доставку. Лучшим примером очереди служит почтовый запрос. Когда пользователь зарегистрирован, Web-приложение публикует сообщения в очередь /myapp/mail/user-registration. На эту очередь может быть подписано несколько почтовых приложений. Если таковых нет, сообщение все равно не будет потеряно.
  • Тема - сообщения доставляются в темы, и их получает каждый подписчик. Темы, как правило, не постоянны. Примером темы для программы мониторинга может служить /event/system/cpu/usage, куда источник регулярно посылает данные о загрузке процессора. Подписчиков может быть любое количество (в том числе ноль) в зависимости от заинтересованности.
Публикация/подписка
Событийно-управляемые решения реализуют модель публикации/подписки. Источники событий публикуют события в программы для обработки, а потребители подписываются на их получение. Способ подписки зависит от программного обеспечения. В приложениях обмена сообщениями потребители подписываются на каналы (возможно, с применением правил фильтрации, например, по типу события). В CEP, таких как Esper, подписка может осуществляться через SQL-запрос, определяющий, в каких событиях вы заинтересованы.

Зачем использовать событийно-управляемые решения?

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

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

Одним из преимуществ управляемой событиями архитектуры является лучшая масштабируемость. Масштабируемость - это способность системы решать поставленные задачи, адаптируясь к изменениям спроса, объема и интенсивности сообщений. Благодаря отсутствию ожидания, управляемые событиями архитектуры обычно лучше работают и имеют более высокую производительность.

Еще одно преимущество касается разработки и поддержки приложения. В событийно-управляемых решениях каждый компонент приложения может быть полностью изолирован и независим.

Событийно-управляемые решения обеспечивают лучшее время реакции благодаря пониженной латентности связи.


Применение событийно-управляемых решений в Интернете

В прошлом Web-инфраструктуры полагались на традиционную модель запрос-ответ, что приводило к необходимости обновления страниц. С появлением Ajax, Reverse Ajax и таких мощных инфраструктур, как CometD и Atmosphere, в Интернете стало легко применять идеи событийно-управляемой архитектуры с ее преимуществами независимости, масштабируемости и реактивности.

На стороне клиента

Управляемая событиями архитектура может быть применена на стороне клиента для разработки графического интерфейса пользователя. Вместо традиционных Web-страниц можно создать одну Web-страницу, выступающую в качестве контейнера. Каждый компонент (часть страницы) может быть изолирован. Можно организовать графический Web-интерфейс пользователя на Java Swing, подобный странице Google, содержащей гаджеты (см. ссылку в разделе Ресурсы).

Для этого потребуется шина событий. Например, можно написать на JavaScript шину событий, которая позволяет каждому компоненту страницы подписываться и публиковаться в каналах. События можно синхронизировать, чтобы после поступления двух или нескольких событий вызывать то или иное действие. Шину событий можно использовать для локальных событий, происходящих на странице, или добавить плагины для поддержки удаленных событий, используя CometD или Socket.IO.

На стороне сервера

На стороне сервера нужно настроить инфраструктуру Reverse Ajax, поддерживающую событийно-управляемую архитектуру. Из всех инфраструктур, рассмотренных в предыдущих статьях этого цикла, только в CometD реализован событийно-ориентированный подход. Для других инфраструктур необходимо разработать собственными силами нетривиальную поддержку. Также можно добавить стороннюю систему обмена сообщениями, такую как JMS (например, Apache ActiveMQ), или CEP, такую как Esper. Более простое решение ― это система Redis, которая поддерживает публикацию/подписку.

Этот цикл статей посвящен Web и Reverse Ajax, управляемым событиями, поэтому мы сосредоточимся на стороне клиента и не будем создавать сложную систему обмена сообщениями.


Пример событийно-управляемого Web

Например, в этой статье мы создадим Web-приложение чат-рума с панелью, содержащей список подключенных пользователей. Ваше имя пользователя будет выделено жирным шрифтом, имена других активных пользователей (которые оставались активными в течение 20 секунд) - зеленым, неактивных в течение 20 секунд ― оранжевым. Если пользователь подключается или отключается, список обновляется.

В целях безопасности в файле web.xml установлен тайм-аут на две минуты. После двух минут бездействия появляется всплывающее окно, и выполняется переадресация на страницу входа.

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

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

Наше Web-приложение управляется событиями. По приведенной выше информации легко определить несколько событий:

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

Некоторые события являются локальными для Web-приложения. Они определяются в локальной шине, как показано в листинге 1.

Листинг 1. Настройка шины
bus = { 
 
    local: new EventBus({ 
        name: 'EventBus Local' 
    }), 
 
    remote: EventBus.cometd({ 
        name: 'EventBus Remote', 
        logLevel: 'warn', 
        url: document.location.href.substring(0, 
            document.location.href.length - 
            document.location.pathname.length) + '/async', 
        onConnect: function() { 
            bus.local.topic('/event/bus/remote/connected').publish(); 
        }, 
        onDisconnect: function() { 
            bus.local.topic('/event/bus/remote/disconnected').publish(); 
        } 
    }) 
 
};

Другие события - удаленные, то есть для их публикации среди всех клиентов нужна система Reverse Ajax, такая как CometD. Наш пример приложения показан на рисунке 1.

Рисунок 1. Пример приложения
Скриншот примера приложения

Пример приложения есть в исходном коде для этой статьи. Многие классы - это вспомогательные (plumbing) классы для обеспечения безопасности или для управления сеансами и пользователями. В данной статье приведены все наиболее важные части кода, но рекомендуется загрузить и запустить пример приложения, чтобы лучше понять, как оно работает.

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

Для настройки событийно-управляемой системы, локальной и удаленной, в примере используется система EventBus от Ovea. Она предоставляет локальную шину событий, мост для CometD, чтобы получать удаленные события, и способ координации событий (для вызова действий после завершения нескольких других). Конечно, при желании можно выбрать другую систему. Пример настройки приведен в виде сценария JavaScript в листинге 1.

После того как шины настроены, приложение и компоненты становятся событийно-ориентированными. В нашем примере настраивается система обнаружения IDLE, как показано в листинге 2.

Листинг 2. Система обнаружения IDLE
bus.local.topic('/event/dom/loaded').subscribe(function() { 
    $.idleTimer(20000); 
    $(document).bind('idle.idleTimer', function() { 
        bus.local.topic('/event/idle').publish('inactive'); 
    }); 
    $(document).bind('active.idleTimer', function() { 
        bus.local.topic('/event/idle').publish('active'); 
    }); 
})

Она отправляет события, как только обнаруживает какую-то деятельность. Этот код может использоваться в любом приложении, где требуется система IDLE. В данном случае его нужно перевести в удаленные события, связанные с деятельностью пользователей. Это также можно сделать на JavaScript, как показано в листинге 3.

Листинг 3. Управление активностью пользователей
bus.local.topic('/event/idle').subscribe(function(status) { 
    bus.remote.topic('/event/user/status/changed').publish({ 
        status: status == 'active' ? 'online' : 'away' 
    }); 
}); 
 
bus.remote.topic('/event/user/status/changed').subscribe(function(evt) { 
    if(evt.user != me.name) { 
        $('#users li').filter(function() { 
            return evt.user == $(this).data('user').name; 
        }).removeClass('online')
          .removeClass('away')
          .addClass(evt.status); 
    } 
});

Первая подписка принимает события от системы IDLE и отправляет на сервер информацию о состоянии пользователя. Другие подписки принимают события, связанные с состоянием пользователя, от сервера. Таким образом, как только состояние пользователя меняется, цвет его имени в списке становится зеленым или оранжевым.

Когда пользователь подключается или отключается, производится передача события, как показано в листинге 4.

Листинг 4. Управление списком пользователей
bus.remote.topic('/event/user/connected').subscribe(function(user) { 
    $('#users ul').append(row(user)); 
}); 
 
bus.remote.topic('/event/user/disconnected').subscribe(function(evt) { 
    $('#users li').filter(function() { 
        return evt.user == $(this).data('user').name; 
    }).remove(); 
});

Код приложения прост, независим и изолирован. Опираясь на разнообразные технологии Ovea, можно быстро создавать событийно-управляемые Web-приложения. Однако это необязательно - вместо Ovea можно использовать другую систему. Разработка этого примера заняла всего один день, причем половина этого времени ушла на вспомогательный код:

  • Maven для сборки проекта;
  • функции обеспечения безопасности (вход, выход, тайм-аут сеанса);
  • сервисы RES с использованием Jersey.

Заключение

В этом цикле статей показано, как создавать гибкие и масштабируемые приложения, удобные для пользователя. Событийно-ориентированные Web-приложения ― довольно молодая концепция. Некоторые Web-инфраструктуры используют ее во внутренних механизмах, но в данной статье показано, что Web-инфраструктура для создания таких приложений не обязательна. Для разделения ответственности между Java-разработчиком и Web-дизайнером вполне достаточно хороших специализированных библиотек. Надеемся, что вы достигли более глубокого понимания того, как сделать управляемую событиями разработку частью своей повседневной работы. Это затягивает: достаточно попробовать, и вам не захочется возвращаться к традиционной схеме.


Загрузка

ОписаниеИмяРазмер
Исходный код примера для статьиreverse_ajaxpt5_source.zip925 КБ

Ресурсы

Научиться

Получить продукты и технологии

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, SOA и web-сервисы
ArticleID=830888
ArticleTitle=Reverse Ajax: Часть 5. Разработка событийно-управляемых Web-приложений
publish-date=08172012