Опубликован: 10.10.2010 | Доступ: свободный | Студентов: 3208 / 299 | Оценка: 4.14 / 3.32 | Длительность: 13:16:00
ISBN: 978-5-9963-0444-8
Специальности: Системный архитектор
Лекция 6:

Использование CORBA

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >

Файл BillingServiceClient.java

BillingServiceClient (пример 6.10) представляет собой клиент, который соединяется с BillingService.Клиент содержит один метод main,который добавляет денежные средства на карту с номером 1 и затем выводит текущий баланс этой карты (строки 29-30). Логика, используемая клиентами для чтения данных в сервисе имен, похожа на логику, применяемую сервером для записи в нее данных.

1  // BillingServiceClient.java
2  package com.asw.corba.ex1;
3
4  import  com.asw.corba.ex1.BillingServiceModule.*;
5  import  org.omg.CosNaming.*;
6  import  org.omg.CORBA.*;
7
8  public class BillingServiceClient {
9  static BillingService BSImpl;
10
11  public static void main(String args[])
12  {
13  try{
14  // create and initialize the ORB
15  ORB orb = ORB.init(args, null);
16
17  // get the root naming context
18  org.omg.CORBA.Object objRef =
19  orb.resolve_initial_references("NameService");
20  // Use NamingContextExt instead of NamingContext. This is
21  // part of the Interoperable naming Service.
22  NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
23
24  // resolve the Object Reference in Naming
25  String name = "BillingService";
26  BSImpl = BillingServiceHelper.narrow(ncRef.resolve_str(name));
27
28  System.out.println("Obtained a handle on server object: " +
BSImpl);
29  BSImpl.addMoney("1",1234);
30  System.out.println(BSImpl.getCardBalance("1"));
31  } catch (Exception e) {
32  System.out.println("ERROR : " + e) ;
33  e.printStackTrace(System.out);
34  }
35  }
36  }
Листинг 6.10. Клиентский класс BillingServiceClient

В строке 15 вызывается статический метод init класса ORB для создания брокера объектных запросов. Массив args типа String позволяет динамически настраивать брокер объектных запросов во время выполнения (массив получен из командной строки). После того как клиент получает ORB, в строках 18-19 вызывается метод resolve_initial_references этого брокера объектных запросов, чтобы получить объектную ссылку на сервис имен. В строке 22 осуществляется приведение полученной объектной ссылки к объекту типа NamingContextExt с помощью метода NamingContextExtHelper.narrow.

Клиент должен запросить у сервиса имен объектную ссылку на сервис, который он разыскивает, - сервис BillingService,имеющий имя "BillingService" (объявлен в классе BillingServiceServer).С помощью метода resolve_str имя сервера "BillingService" передается переменной BSImpl типа BillingService.Статический метод BillingServiceHelper.narrow осуществляет приведение объектной ссылки к требуемому типу производного класса. С этого момента у клиента есть активный распределенный объект.

Желательно сохранять имена сервисов в файлах типа .properties вместо того, чтобы "зашивать" их в исходный текст класса. Включение имен в исходный текст класса требует дополнительного сопровождения файлов классов при изменении имен. Файл свойств дает возможность настраивать уже развернутую систему, тем самым делая настройку вопросом администрирования, а не разработки.

Выполнение примера

Для выполнения примера требуется следующая последовательность действий:

  1. скомпилировать IDL -файл с помощью idlj ;
  2. реализовать и скомпилировать серверный класс;
  3. реализовать и скомпилировать клиентский класс;
  4. запустить сервис именования;
  5. запустить сервер;
  6. запустить клиент.

Для компиляции IDL -файла из командной строки используется компилятор idlj,входящий в состав пакета jdk фирмы Sun. Неполный список опций командной строки idlj выглядит так:

  • -f<client | server | all>
  • -pkgPrefix <имя модуля или тип IDL> <добавляемый префикс>
  • -td <выходной каталог>

Опция -f управляет созданием кода для заглушек и скелетов. Опция -fclient создает только клиентские файлы, -fserver - только серверные файлы, а -fall - и те, и другие. Опция -pkgPrefix генерирует имена пакетов. Эта опция используется с именем модуля. При компиляции модуля с именем modeName с опциями -pkgPrefix modeName prefix будут созданы файлы Java с именем пакета prefix.modeName.Опция -td предписывает записывать созданные файлы в указанный каталог.

Например, если исходный код находится с каталоге C:\src,командная строка будет выглядеть следующим образом (исходя из IDL -описания, представленного в примере 6.1):

idlj -td c:\src -pkgPrefix BillingServiceModule com.asw.corba.ex1 
   -fall BillingService.idl

Эта командная строка создает и серверные, и клиентские файлы CORBA-Java. После реализации сервера и клиента скомпилируйте серверный и клиентский код. При компиляции никаких особенностей нет, все, что необходимо сделать - написать в командной строке

javac *.java

находясь в директории проекта. Необходимо проследить, чтобы пакет org.omg.*,содержащий реализацию поддержки CORBA, присутствовал в путях classpath.

Для того чтобы запустить нашу систему, кроме запуска клиентской и серверной части нам необходимо запустить сервис имен. Мы воспользуемся сервисом имен, который входит в состав пакета jdk и называется tnameserv.exe - базовая реализация CORBA Object Service ( COS ) Naming Service. tnameserv не является готовым средством, реализующим сервис имен; скорее, оно служит средством тестирования, позволяющим проверить правильность взаимодействия клиентов и серверов. Сервис имен должен быть приведен в активное состояние до того, как будет запущен сервер. Поскольку нашей целью было создание распределенного приложения, предположим, что сервис имен будет работать на узле с именем alpha, серверный объект - на узле с именем beta,а клиент - на узле с именем gamma. Предполагаем, что на всех узлах установлен пакет jdk.

На узле alpha запускаем сервис имен:

H:\j2sdkL4.2_06\bin\tnameserv.exe

Выполнение команды приведет к следующему результату:

Initial Naming Context:
IOR:000000000000002b49444c3a6f6d672e6f72672f436f734e616d696e672f4e 616d696e67436f
6e746578744578743a312e30000000000001000000000000008000010200000000 0c3139322e3136
382e312e31000384000000000035afabcb00000000202ba83e8000000001000000 00000000010000
000d544e616d65536572766963650000000000000004000000000a000000000000 01000000010000
00200000000000010001000000020501000100010020000101090000000100010100
TransientNameServer: setting port for initial object references
to: 900
Ready.

По умолчанию сервис ожидает обращений на 900 порте, однако иногда этот порт доступен только для администраторов. После того как сервис имен запущен, мы можем запустить на узле beta серверный объект:

G:\BillingService >java com.asw.corba.ex1.BillingServiceServer 
  -ORBInitialHost=alpha

Результат выполнения предыдущей команды:

BillingServiceServer ready and waiting ...

Мы должны каким-то образом указать, где находится сервис имен. Это делается с помощью ключей ORBInitialHost и ORBInitialPort. Именно эти параметры командной строки и передаются при инициализации orb в метод init. Поскольку мы использовали порт по умолчанию, параметр ORBInitialPort можно не указывать.

Далее на узле gamma мы запускаем клиента:

G:\BillingService>java com.asw.corba.ex1.BillingServiceClient 
  -ORBInitialHost=alpha

Выполнение команды:

Obtained a handle on server object:
BillingServiceApp._BillingServiceStub:IOR:00000000000000174944
4c3a48656c6c6f4170702f48656c6c6f3a312e3000000000000100000000000000
6c000102000000
000c3139322e3136382e312e31000bd2000000000021afabcb00000000202baba5 49000000010000
00000000000000000004000000000a000000000000010000000100000020000000 00000100010000
00020501000100010020000101090000000100010100 1234

Поскольку клиент тоже нуждается в сервисе имен для получения объектной ссылки, ему также передается имя узла, на котором сервис имен запущен. Далее клиент получает объектную ссылку, распечатывает ее, вызывает метод addMoney и метод getCardBalance сервера, распечатывает строку, которую ему этот метод вернул, и, наконец, сервер выводит строку:

BillingServer Exiting ...

и прекращает работу.

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

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >
Алмаз Мурзабеков
Алмаз Мурзабеков
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type"


Java version 1.7.0_05