Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы Мартын 1(ComCorbaLab2004).doc
Скачиваний:
30
Добавлен:
10.02.2016
Размер:
1.81 Mб
Скачать

5.5. Создание сервера

Сервер — это программа, предоставляющая некий сервис, удаленные объекты в случае с CORBA. Серверы CORBA могут активизироваться самостоятельно, будучи запущенными системным администратором либо при загрузке операционной системы. Также программист может зарегистрировать серверы CORBA с помощью утилит, после чего специальный демон будет отслеживать входящие запросы программ-клиентов и активизировать нужные серверы автоматически. Для этой цели в VisiBroker for C++ имеется OAD (Object Activation Daemon), в VisiBroker for Java — OADJ.

Написать сервер не так сложно, как это может показаться. Схематично процесс работы типичного CORBA-сервера описывается всего несколькими шагами:

  • инициализация брокера объектных запросов (далее ORB);

  • инициализация объектного адаптера;

  • создание экземпляра CORBA-объекта;

  • экспорт созданного экземпляра;

  • переход в состояние ожидания запросов.

Инициализация ORB нужна для создания коммуникационного канала между клиентом и объектами. Ниже приведен вариант инициализации для обеих (С++ иJava) версий VisiBroker. Метод инициализации ORB принимает аргументы командной строки, с помощью которых можно производить тонкую настройку системы:

Для Си++:

CORBA::ORB_var orb = CORBA::ORB_init

(argc, argv);

Для Java:

org.omg.CORBA.ORB orb = org.omg

.CORBA.ORB.init(args,System.

getProperties());

Объектный адаптер в CORBA играет особую роль. Это по сути координатор действий. Если ORB не отличается интеллектом и просто выполняет транспортные функции, то объектный адаптер занимается сложной работой по запуску и экспорту объектов, а также заведует информацией, хранящейся в репозитарии реализаций (implementation repository) — специальном хранилище данных, которым пользуется демон активизации объектов. Если сравнивать ORB с системной шиной компьютера, то объектный адаптер нечто вроде драйвера платы расширения.

В спецификации CORBA упоминаются два типа объектных адаптеров — основной (BOA) и переносимый (POA). Последний постепенно вытеснит BOA, но окончательно станет доступным лишь в четвертой версии VisiBroker. Пока будет использоваться BOA.

Инициализация BOA выглядит так:

Для Си++:

CORBA::BOA_var boa = orb->BOA_init(argc, argv);

Для Java:

org.omg.CORBA.BOA boa=((com.visigenic

.vbroker.orb.ORB)orb). BOA_init();

Существуют разные методы инициализации BOA — с передачей параметров командной строки и без них, поэтому на примере выше показаны две разные вариации.

Перед созданиемсобственно объектанадо уточнитьпонятие объектав терминологии, заложенной в спецификации CORBA 2.3. Объект — это абстрактная, не зависящая от языка реализации сущность, которой оперируют разработчики и пользователи при описании работы системы. Физическая же реализация объекта на языке программирования, генерируемая компилятором IDL, называется сервант.

Объект создается тривиальным вызовом конструктора класса его серванта:

Для Си++:

ServiceImpl implObject(”ServiceObj”);

Для Java:

Test.Service implObject = new Test

.ServiceImpl(”ServiceObj”);

Разница между реализациями на языках Cи++ и Java состоит лишь в способе его вызова. Язык Cи++ умеет создавать объекты на стеке, поэтому достаточно описать локальную переменную. В Java экземпляры объектов всегда создаются динамически с помощью ключевого слова new. Все это сделано не случайно: использование локальной переменной в Си++ гарантирует вызов деструктора серванта при покидании блока, где он описан. Если создавать объект динамически, то позже придется удалять его явным вызовом ключевого слова delete. Напротив, Java может позволить себе динамическое создание серванта, потому что в конце работы он будет уничтожен сборщиком мусора виртуальной машины.

Оба серванта создаются с параметром, задающим имя для их экземпляров. Это позволяет клиенту найти конкретный экземпляр объекта по имени. Клиент, который при попытке подключиться к объекту не указывает его имя, получит ссылку на произвольный экземпляр запрашиваемого объекта с любого сервера в сети. Такой вариант удобен, когда в CORBA-системе имеется механизм балансировки загрузки серверов. Так или иначе сервант с именем реализует долгоживущий (persistent) объект, т.е. такой объект, который может пережить свой сервер. Конечно, уничтожив программу-сервер, породившую сервант (а вместе с ним и объект), уничтожают все, что им было запущено, в том числе и серванты с объектами. Говоря о продолжительности жизни, следует думать о долгоживущих объектах как о сущностях, состояние которых можно как-то сохранить, и впоследствии при следующем запуске сервера восстановить объекты в том виде, который они имели во время предыдущей сессии. Если создаетсяобъект, описывающий банковский счет, то его лучше делать долгоживущим, потому что данные (например, сумма на счету), из которых складывается состояние объекта, не должны изменяться только потому, что администратор остановил сервер и запустил его на следующий день. Напротив, объект «Часы» не имеет смысла делать долгоживущим — после перезапуска сервера время будет безнадежно сбито, и уж лучше заново обратиться к службе точного времени (вот воистину образцовый долгоживущий объект!) и получить текущее время. Так что во многих книгах по CORBA имеет место терминологическая путаница. Следует отметить, что такие утилиты, как Object Activation Daemon и Smart Agent, регистрируют лишь долгоживущие объекты.

Другой тип объектов — временные (transient) — существует лишь в рамках того процесса, который запустил их серванты. Отслужив свой срок, временный объект «умирает». Как правило, временные объекты являются утилитами, а не сущностями. В примере с банковским счетом временными объектами будут утилиты для изменения суммы на счету, а в примере с часами временный объект может служить программным интерфейсом к службе точного времени. Как бы то ни было, после выключения сервера состояние временных объектов никого уже не интересует — в следующий раз можно создать новые объекты.

Создать временный объект легко: просто используетсядля его серванта конструктор без параметров. Таким образом, любой безымянный объект по умолчанию будет временным — зачем несколько одинаковых долгоживущих объектов с одинаковым состоянием?! Тем не менее в CORBA есть средства и для создания именованных временных объектов.Ссылку на временный объект программа-клиент сможет получить лишь в том случае, если она вернется как результат выполнения некоторого запроса к другому объекту или как параметр вызова, описанный на IDL в виде out или inout.

Где взять сервант?Написать!Если не используютсяспециальные возможности CORBA,например, Dynamic Skeletons (DSI), то это несложно, хотя между реализациями на Cи++ и на Java разница размером в пропасть. С Java все проще простого. После трансляции IDL получаютсяне только системные классы, но и пример описания класса серванта. Имя класса будет соответствовать имени интерфейса, но к нему будет добавлен префикс _example_ (например: _example_Service для IDL-интерфейса с именем Service), и найти его можно в одноименном файле с расширением .java. По сути дела, это уже готовый сервант. Можноскопировать его и изменить по своему усмотрению, а можнопросто проконсультироваться с ним. idl2cpp подобными излишествами разработчика не балует, поэтому писать сервант нужно вручную.Важно понять, что техника создания серванта использует наследование его от класса скелета, который генерируется компилятором IDL автоматически. Найти его просто. В Java-реализациях имя класса скелета состоит из имени IDL-интерфейса с префиксом _ и суффиксом ImplBase (например: _ServiceImplBase). VisiBroker for С++ все еще использует устаревшую схему именования скелетов, и имя таких классов состоит из имени IDL-интерфейса с префиксом _sk_ (_sk_Service). В любом случае класс создаваемого серванта наследуется от скелета, и требуется реализовать только те методы, которые относятся кпректируемомуобъекту, и ни в коем случае не трогать остальные. Как обнаружить нужные методы? В версиях для Cи++можно заглянутьв файл, имя которого заканчивается на _s.hh, и найтив описании класса скелета все чистые виртуальные методы. Там же idl2cpp оставляет специальный комментарий:

// The following operations need to be implemented

При использовании Java-версии VisiBroker необходимо найтикласс, чье имя совпадает с именем IDL-интерфейса, и ознакомитьсяс его методами — все они потребуют реализации в серванте.

Стоит вернуться к разбору порядка действий сервера. Завершающим штрихом к его запуску будет экспорт объекта и переход в состояние ожидания:

Для Си++:

boa->obj_is_ready(&implObject);

boa->impl_is_ready();

Для Java:

boa.obj_is_ready(implObject);

boa.impl_is_ready();

Первая строчка, вызывающая метод obj_is_ready, сообщает через адаптер объектов, что сервант готов обслуживать запросы. Если объекты долгоживущие, то BOA попутно зарегистрирует их в таблице запущенных объектов, которую ведет утилита Smart Agent. С этого момента объект может использоваться клиентами и другими объектами. А чтобы предотвратить завершение серверного приложения, его сознательно блокируют вызовом impl_is_ready(). В результате происходит остановка потока, на котором выполняется приложение-сервер. Разблокировать его можно, лишь вызвав из другого потока метод shutdown() серванта или вручную закрыв приложение сервера. Следует отметить, что нет нужды вызывать impl_is_ready(), если в серверном приложении уже имеется свой цикл обработки сообщений — пусть он и следит за временем жизни сервера.