/>/>/>Факультет«Информатика и системы управления»
Методические указания к лабораторной работе
по курсу «Распределенныесистемы обработки информации»
«Реализацияпочтового клиента и сервера на основе CORBA»
Москва, 2004 г.
/>/>/>/>/>/>Цель работы
1. Познакомиться с технологией CORBA.
2. Познакомитьсяс языком IDL и описанием интерфейсов.
3. Освоитьклассы библиотеки org.omg.
4. Применить полученные знания на практике/>/>/>/>/>/>/> 1. Задание для домашней подготовки
Ознакомитьсяс теоретическим материалом, представленным в приложениях к данным методическимуказаниям и примерами программ. Ознакомиться с текстом задания к лабораторнойработе, предложить размещение компонентов и функциональность, удовлетворяющуютребованиям задания к лабораторной работе, и написать программу./>/>/>/>/> 2. Задание к лабораторной работе
Разработать почтовыйклиент и сервер. Клиент – оконное приложение, которое будет позволять отсылатьи получать с сервера сообщения. Идентификация клиентов на сервере, протоколпередачи сообщений – на усмотрение студентов.
Сервер можетбыть консольным приложением. Хранить сообщения можно в текстовом файле.Рекомендуется сделать сервер многопоточным.
Длявзаимодействия клиента и сервера использовать технологию CORBA.
В качестведополнения предлагается сервер или клиент реализовать не на Java.
/>/>/>/>/>/>3. Содержание отчета
Отчетдолжен содержать:
1. Постановкузадачи, решаемой отлаженной программой.
2. Руководствопользователя отлаженной программы, содержащее описание интерфейсов всех функцийпрограммы.
3. Листингпрограммы с необходимыми комментариями./>/>/>/>/>/>4. Контрольные вопросы
1. Что такое CORBA?
2. Чтотакое IDL? Для чего он нужен?
3. Какосуществляется взаимодействие клиента и сервера в CORBA?
4. Какпередаются данные между ними?
5. Длячего нужен сервер имен?
6. Как запускаетсяCORBA‑сервер?/>/>/>/>/>5. Литература
1. КенАрнольд, Джеймс Гослинг, Дэвид Холмс. Язык программирования Java™.
2. Официальныйсайт Java – java.sun.com/ (есть раздел на русском языке с учебником).
3. Java™ 2 SDK, Standard Edition Documentation – java.sun.com/products/jdk/1.5/index.html.
4. ДжеймсГослинг, Билл Джой, Гай Стил. Спецификация языка Java (The Java Language Specification – www.javasoft.com/docs/books/jls/). Перевод на русский язык –http://www.uni-vologda.ac.ru/java/jls/index.html
5. Официальныйсайт проекта Eclipse – www.eclipse.org/.
/>/>/>/>6. Приложение 1. />/>CORBA
Технология CORBA (Common Object Request Broker Architecture) – это стандарт написанияраспределенных приложений, предложенный консорциумом OMG (Open Management Group). Создавая CORBA‑объекты,мы можем, например, существенно уменьшить время решения задач, требующихвыполнения большого объема вычислений. Это возможно благодаря размещению CORBA‑объектовна разных машинах. Каждый удаленный объект решает определенную подзадачу, темсамым разгружает клиент от выполнения лишней работы.
Основу CORBAсоставляет объектный брокер запросов (Object Request Broker). ORB управляетвзаимодействием объектов в распределенной сетевой среде. IIOP (InternetInter-ORB Protocol) – это специальный протокол взаимодействия между ORB.
В адресномпространстве клиента функционирует специальный объект, называемый заглушкой(stub). Поучив запрос от клиента, он упаковывает параметры запроса вспециальный формат и передает его серверу, а точнее скелету.
Скелет(skeleton) – объект, работающий в адресном пространстве сервера. Получив запросот клиента, он распаковывает его и передает серверу. Также скелет преобразуетответы сервера и передает их клиенту (заглушке).
Для тогочтобы написать любое приложение CORBA используя технологию Java, необходимо иметьдве вещи – это установленный пакет JDK1.5 и компилятор idlj (…\jdk1.5.0\bin\idlj.exe). JDK предоставляетнабор классов для работы с CORBA объектами, а idlj производит отображение языкаIDL в Java.
6.1 Создание простейшего CORBA-приложения
/>/>6.1.1 Написание интерфейса
Создание CORBA приложения на Java начинается с написанияинтерфейса для удаленного объекта, используя язык описания интерфейсов (Interface Definition Language, IDL).
Создадим файл hello.idl
module HelloApp
{
interface Hello
{
string sayHello();
oneway void shutdown();
};
};
Данныйинтерфейс описывает лишь два метода shutdown и sayHello. Причем, нам не важно,что делают эти методы, главное мы определяем, что они есть и определяем какие уних входные и выходные параметры.
Далее следуетзапустить компилятор IDL-to-Java idlj:
idlj – fall Hello.idl
В текущейдиректории появилась новая папка HelloApp, в которой содержаться шесть java‑файлов.Каждый из них имеет свое назначение.
· HelloPOA.java java – абстрактный класс, который представляет собой ни что иное,как скелет сервера (skeleton) и обеспечивает функциональность сервера.
· _HelloStub.java – класс, реализующий заглушку (stub) клиента. Обеспечиваетфункциональность клиента.
· HelloHelper.java и HelloHolder.java – классы, предоставляющие вспомогательные функции для CORBA объектов.
· HelloOperations.java – класс, содержащий описание интерфейса hello на языке Java.
· Hello.java – класс – наследник HelloOperations, поддерживающий интерфейс org.omg.CORBA. Object.6.1.2 Создание сервера
Теперь нашазадача – написать класс, реализующий интерфейс hello. В нашем случае этобудет HelloImpl. Обратите внимание, на то, что он является наследникомкласса HelloPOA. В HelloImpl реализованы методы, объявленные в Hello.idl.
Дляупрощения задачи объявление методов можно взять из файла HelloOperations.java, сгенерированного jdlj.
class HelloImpl extends HelloPOA {
private ORB orb;
public void setORB (ORB orb_val) {
orb = orb_val;
}
// implement sayHello() method
public String sayHello() {
return «\nHello world!!\n»;
}
// implement shutdown() method
public void shutdown() {
orb.shutdown(false);
}
}
Следующимшагом будет создание собственно серверной части приложения. Это будет класс HelloServer.
В нем будетвсего один метод – стандартная функция main.
Первое что мыделаем, создаем ORB. Затем создаем экземпляр класса удаленного объекта (HelloImpl) и регистрируем его вORB. Дальше вызываем специальную службу имен (NameService) и регистрируем в нейимя удаленного объекта, чтобы клиент смог его найти.
Рассмотримподробнее эти этапы.
1. Создание иинициализация ORB. Производится вызовом статического метода init классаORB
ORBorb = ORB.init (args, null);
2. Создание экземпляракласса удаленного объекта и регистрация его в ORB
HelloImplhelloImpl = new HelloImpl();
helloImpl.setORB(orb);
3.Получение контекста имен(NamingContext)
org.omg.CORBA.Object objRef = orb.resolve_initial_references («NameService»);
NamingContextExtncRef = NamingContextExtHelper.narrow(objRef);
В первойстрочке мы получаем объектую ссылку на службу имен (NameService). Но фактическиэто обыкновенный CORBA‑объект и для того, чтобы использовать его какконтекст имен (NamingContext), необходимо вызвать метод narrow класса NamingContextHelper,который как бы конкретизирует данный CORBA‑объект.
4. Регистрацияимени удаленного объекта (HelloImpl)
Stringname = «Hello»;
NameComponentpath[] = ncRef.to_name(name);
ncRef.rebind (path, href);
Регистрация именипроизводится для того, чтобы клиент смог найти удаленный объект. Этой целислужит функция rebind (NameComponent[] nc, Object obj) интерфейса NamingContext.
5. Ожиданиезапросов от клиента
orb.run();
Теперь серверготов к работе.
// HelloServer.java
import HelloApp.*;
import org.omg. CosNaming.*;
import org.omg. CosNaming. NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg. PortableServer.*;
import org.omg. PortableServer.POA;
import java.util. Properties;
class HelloImpl extends HelloPOA {
private ORB orb;
public void setORB (ORB orb_val) {
orb = orb_val;
}
// implement sayHello() method
public String sayHello() {
return «\nHello world!!\n»;
}
// implement shutdown() method
public void shutdown() {
orb.shutdown(false);
}
}
publicclass HelloServer {
publicstatic void main (String args[]) {
try{
//create and initialize the ORB
ORBorb = ORB.init (args, null);
//get reference to rootpoa & activate the POAManager
POArootpoa = POAHelper.narrow (orb.resolve_initial_references («RootPOA»));
rootpoa.the_POAManager().activate();
//create servant and register it with the ORB
HelloImplhelloImpl = new HelloImpl();
helloImpl.setORB(orb);
//get object reference from the servant
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
Hellohref = HelloHelper.narrow(ref);
//get the root naming context
//NameService invokes the name service
org.omg.CORBA.Object objRef =
orb.resolve_initial_references(«NameService»);
//Use NamingContextExt which is part of the Interoperable
//Naming Service (INS) specification.
NamingContextExtncRef = NamingContextExtHelper.narrow(objRef);
//bind the Object Reference in Naming
Stringname = «Hello»;
NameComponentpath[] = ncRef.to_name(name);
ncRef.rebind(path, href);
System.out.println(«HelloServer ready and waiting…»);
//wait for invocations from clients
orb.run();
}
catch(Exception e) {
System.err.println(«ERROR:» + e);
e.printStackTrace(System.out);
}
System.out.println(«HelloServer Exiting…»);
}
}
/>/>/>6.1.3 Создание клиента
Перейдем кнаписанию кода для клиента.
Основныешаги написания клиентского приложения
1. Создание и инициализация ORB
2. Получениеконтекста службы имен (NamingContext)
3. Нахождение удаленного объекта
4. Вызов метода sayHello.
5. Вызов метода shutdown.
Как видно,первые два пункта совпадают с этапами создания серверного приложения, поэтомурассматривать их не будем.
Третий пунктреализуется тоже достаточно просто. Создается объект NameComponent. Вызывается метод resolve (NameComponent[] path), который отыскивает поимени удаленный объект (стандартный CORBA‑объект). При помощи метода narrow(org.omg.CORBA. Objectobj) класса helloHelper (сгенерированного idljкомпилятором) получаемобъектную ссылку на интерфейс hello.
Stringname = «Hello»;
helloImpl= HelloHelper.narrow (ncRef.resolve_str(name));
Теперь можновызывать метод sayHello:
System.out.println(helloImpl.sayHello());
Метод shutdown завершает работы сервера.
helloImpl.shutdown();
//testClient.java
importHelloApp.*;
importorg.omg. CosNaming.*;
importorg.omg. CosNaming. NamingContextPackage.*;
importorg.omg.CORBA.*;
publicclass HelloClient
{
staticHello helloImpl;
publicstatic void main (String args[])
{
try{
//create and initialize the ORB
ORBorb = ORB.init (args, null);
//get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references(«NameService»);
//Use NamingContextExt instead of NamingContext. This is
//part of the Interoperable naming Service.
NamingContextExtncRef = NamingContextExtHelper.narrow(objRef);
//resolve the Object Reference in Naming
Stringname = «Hello»;
helloImpl= HelloHelper.narrow (ncRef.resolve_str(name));
System.out.println(«Obtained a handle on server object:» + helloImpl);
System.out.println(helloImpl.sayHello());
helloImpl.shutdown();
}catch (Exception e) {
System.out.println(«ERROR:» + e);
e.printStackTrace(System.out);
}
}
}
6.1.4 Компиляция и запуск приложения
Файлы HelloServer.java and HelloClient.java, Hello.idl и папка HelloApp, созданная idkj.exe должны храниться в однойпапке.
Для компиляцииклиента и сервера надо в командной строке набрать
javac *.javaHelloApp/*.java
javac.exe находится в …\jdk1.5.0\bin.
Среда Eclipse не позволяет запускать CORBA‑приложения. Длязапуска
1. Запустить службуorbd – Object Request Broker Daemon (…\jdk1.5.0\bin\orbd.exe). Это делается, чтобы мысмогли получить ссылку на службу имен.
start orbd – ORBInitialPort 1050
Параметр – ORBInitialPort – номер порта, накотором будет работать сервер имен.
2.Запуск сервера
startjava HelloServer – ORBInitialPort 1050 – ORBInitialHost localhost
Указываетсяпорт, на котором работает сервер имен. Параметр – ORBInitialHost указываетхост, на котором работает сервер имен.
3.Запуск клиента
javaHelloClient – ORBInitialPort 1050 – ORBInitialHost localhost
Указываетсяпорт, на котором работает сервер имен. Параметр – ORBInitialHost указываетхост, на котором работает сервер имен.
Для удобствакомпиляции и запуска можно создать bat‑файл:
idlj– fall Hello.idl
javac*.java HelloApp/*.java
startjava HelloServer – ORBInitialPort 1050 – ORBInitialHost localhost
javaHelloClient – ORBInitialPort 1050 – ORBInitialHost localhost
6.2 Язык IDL
Язык OMG IDL (Interface Definition Language – Язык ОписанияИнтерфейсов) представляет собой технологически независимый синтаксис дляописания интерфейсов объектов. При описании программных архитектур, OMG IDL прекрасно используется вкачестве универсальной нотации для определения границ объекта, определяющих егоповедение по отношению к другим компонентам информационной системы. OMG IDL позволяет описыватьинтерфейсы, имеющие различные методы и атрибуты. Язык также поддерживаетнаследование интерфейсов, что необходимо для повторного использования объектовс возможностью их расширения или конкретизации.
IDL является чистодекларативным языком, то есть он не содержит никакой реализации. IDL‑спецификации могутбыть откомпилированы (отображены) в заголовочные файлы и специальные прототипысерверов, которые могут использоваться непосредственно программистом. То есть IDL‑определенныеметоды могут быть написаны, а затем выполнены, на любом языке, для которогосуществует отображение из IDL. К таким языкам относятся C, C++, SmallTalk, Pascal, Java, Ada.
С помощью IDL можно описать и атрибутыкомпоненты, и родительские классы которые, она наследует, и вызываемыеисключения, и, наконец, методы, определяющие интерфейс, причем с описаниемвходных и выходных параметров.
Структура CORBA IDL файла выглядит следующимобразом:
module {
;
;
;
interface [:] {
;
;
;
;
[]()
[raises exception] [context]
.
.
[]()
[raises exception] [context]
.
.
}
interface [:]
.
.
}
Синтаксисязыка IDL довольно объемный и не представляется возможным описать его вметодическом пособии.
Дляреализации интерфейса почтового сервера можно дополнить Hello.idl
moduleHelloApp
{
structTMessage
{
stringTo;
stringFrom;
stringMessage;
};
typedefsequence TMessages;
interfaceHello
{
TMessagesGetMessages (in string Name, out short count);
onewayvoid Send (in string Client, in string Name, in string Message);
stringsayHello();
onewayvoid shutdown();
};
};
typedefsequence TMessages; – объявление типа динамический массив сообщений TMessage.