Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Распределенные вычислительные сети..pdf
Скачиваний:
20
Добавлен:
05.02.2023
Размер:
5.91 Mб
Скачать

144

серверу имен и получать от него координаты доступа к RmiPadServer. Все это скрыто внутри технологии RMI, требует знания основ администрирования сетей ЭВМ и обсуждается на лабораторных и практических занятиях.

3.3.3 Реализация RMI-клиента

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

Сначала, в проекте создадим файл интерфеса с именем RmiPad и перенесем в него содержимое файла RmiPad.java из проекта proj12. Это необходимо для того, чтобы клиентская программа могла работать с описанием интерфейса удаленного объекта.

Затем, в проекте proj13 создадим класс с именем RmiPadClient и пакетным префиксом asu.rmiclient, а первоначальное содержимое его скопируем из класса OrbPadClient проекта proj11, в котором уже реализовано приложение клиента, но для технологии CORBA.

После необходимых изменений, мы получим приложение RMI-клиента, показанное на листинге 3.9.

Листинг 3.9 — Исходный текст клиента RmiPadClient из среды Eclipse EE

package asu.rmiclient;

import java.io.IOException; import java.rmi.Naming; import asu.rvs.rmi.RmiPad;

/**

*Реализация клиента распределенного объекта RmiPad

*@author vgr

*/

public class RmiPadClient {

/**

*Метод чтения целого числа со стандартного ввода

*@return целое число или -1, если - ошибка.

*/

public int getKey()

{

int ch1 = '0'; int ch2 = '9'; int ch; String s = "";

try

{

while(System.in.available() == 0) ;

while(System.in.available() > 0)

{

ch = System.in.read();

if (ch == 13 || ch < ch1 || ch > ch2)

145

continue; if (ch == 10)

break;

s += (char)ch;

};

if (s.length() <= 0) return -1;

ch = new Integer(s).intValue(); return ch;

}

catch (IOException e1)

{

System.out.println(e1.getMessage()); return -1;

}

}

/**

*Метод чтения строки текста со стандартного ввода

*@return строка текста.

*/

public String getString()

{

String s = "\r\n"; String text = ""; int n;

char ch; byte b[];

try

{

//Ожидаем поток ввода while(System.in.available() == 0) ; s = "";

while((n = System.in.available()) > 0)

{

b = new byte[n]; System.in.read(b); s += new String(b);

};

//Удаляем последние символы '\n' и '\r' n = s.length();

while (n > 0)

{

ch = s.charAt(n-1);

if (ch == '\n' || ch == '\r') n--;

else

break;

}

//Выделяем подстроку

if (n > 0)

text = s.substring(0, n);

else

text = ""; return text;

}

catch (IOException e1)

146

{

System.out.println(e1.getMessage()); return "Ошибка...";

}

}

public static void main(String[] args)

{

System.out.println(

 

 

"RmiPadClient для работы с удаленным объектом RmiPad.\n"

+

"\t1)

если

ключ - пустой,

то завершаем программу;\n"

+

"\t2)

если

текст - пустой,

то удаляем по ключу;\n"

+"\t3) если текст - не пустой, то добавляем его.\n"

+"Нажми Enter - для продолжения ...\n"

+ "-----------------------------------------

");

// Создаем объект локального класса RmiPadClient rpc =

new RmiPadClient(); rpc.getKey();

try{

//Получаю и печатаю список всех регистраций. String[] sss =

Naming.list("//localhost:1099/RmiPad"); for(int i=0; i<sss.length; i++)

System.out.println(sss[i]);

//Получаю объектную ссылку на удаленный объект RmiPad rmipad =

(RmiPad)Naming.lookup("//localhost:1099/RmiPad");

/** * Основной цикл приложения */

int ns; // Число прочитанных строк int nb; // Число прочитанных байт String text, s; // Строка введенного текста String[] ls;

// Цикл обработки запросов

 

while(true)

 

{

 

//Печатаем заголовок ответа

 

System.out.println(

 

"----------------------------------------

\n"

+ "Ключ\tТекст\n"

 

+ "----------------------------------------

");

ls = rmipad.getList();

 

//Выводим (построчно) результат запроса к БД

 

ns = 0;

 

nb = ls.length;

 

while(ns < nb){

 

System.out.println(ls[ns] + "\n");

 

ns++;

 

}

 

// Выводим итог запроса

 

System.out.println(

 

"----------------------------------------

\n"

147

+"Прочитано " + ls.length + " строк\n"

+"----------------------------------------\n"

+"Формируем новый запрос!");

System.out.print("\nВведи ключ

или Enter: ");

nb = rpc.getKey();

 

 

if (nb == -1)

 

 

 

break;

//

Завершаем работу программы

System.out.print("Строка текста или Enter: "); s = rpc.getString();

text = s;

while (s.length() > 0)

{

System.out.print("Строка текста или Enter: "); s = rpc.getString();

if(s.length() <= 0) break;

text += ("\n" + s);

}

if (text.length() <= 0)

{

ns = rmipad.setDelete(nb); if (ns == -1)

System.out.println("\nОшибка удаления строки !!!");

else

System.out.println("\nУдалено " + ns + " строк...");

}

else

{

ns = rmipad.setInsert(nb, text); if (ns == -1)

System.out.println("\nОшибка добавления строки !!!");

else

System.out.println("\nДобалено " + ns + " строк...");

}

System.out.println("Нажми Enter ..."); rpc.getKey();

}

System.out.println("Программа завершила работу...");

}

catch (Exception e)

{

System.out.println("ERROR : " + e) ;

}

}

}

Основное отличие приведенного листинга от текста ORB-клиента (см. листинг 3.6) заключается в том, что RMI-клиент подключает интерфейс удаленного объекта всего лишь одним методом lookup() класса Naming:

148

// Получаю объектную ссылку на удаленный объект RmiPad rmipad =

(RmiPad)Naming.lookup("//localhost:1099/RmiPad");

все остальные изменения связаны только с различными типами разных технологий и приложений.

Запустив на выполнение программу RMI-клиента, можно убедиться в ее работоспособности, как показано на рисунке 3.22.

Рисунок 3.22 — Начало диалога приложения RmiPadClient

3.3.4Завершение реализации RMI-проекта

Взавершении данного подраздела необходимо реализовать и протестировать наше распределенное приложение в виде двух Jar-архивов: rmipadserver.jar

иrmipadclient.jar. Для этого, предварительно нужно:

в среде разработки Eclipse EE: остановить работу RMI-клиента, а затем — RMI-сервера;

в виртуальном терминале остановить работу сервера rmiregistry.

Сначала, проведем архивацию и тестирование серверной части RMI-проек-

та. Для этого, выделим в Eclipse EE проект с именем proj12 и проведем создание архива, как это уже было описано в пункте 3.2.2 данной главы. Сам архив сохраним в файле с абсолютным путом доступа: $HOME/lib/rmipadserver.jar.

Теперь отредактируем переменную среды CLASSPATH, как это показано на рисунке 3.23, чтобы rmiregistry мог найти архив сервера.

Рисунок 3.23 — Редактирование .bashrc для архива RMI-сервера

149

Сохранив изменения в файле .bashrc, запустим новый виртуальный терминал, в котором стартуем сервер rmiregistry. Затем, перейдя в каталог $HOME/lib/, запустим сервер как показано на рисунке 3.24.

Рисунок 3.24 — Запуск RMI-сервера из архива rmipadserver.jar

Хорошо видно, что сервер стартовал — нормально, но здесь надо отметить, что если бы мы не внесли изменения в файл .bashrc, то rmiregistry регистрировал бы приложение, размещенное в проекте proj12 среды Eclipse EE.

Запустив нормально RMI-серверб следует провести:

тестирование RMI-клиента в среде Eclipse EE;

создание архива проекта proj13 и размещение его в каталоге $HOME/lib/;

переход в каталог $HOME/lib/ и запуск RMI-клиента, как это показано на рисунке 3.25.

Тестирование распределенного приложения можно продолжить, запуская приложение RMI-клиента на множестве виртуальных терминалов командами:

java -jar rmipadclient.jar

каждое отдельно запущенное приложение клиента будет работать самостоятельно, но с единой базой данных.

На этом, мы завершаем изучение технологии RMI и всей темы, посвященной объектным распределенным системам. На рисунке 3.26 представлен список и размеры всех созданных в данной главе Jar-архивов приложений. В целом, они посвящены решению одной задачи: ведению записей в таблице notepad базы данных exampleDB, поддерживаемой встроенным вариантом СУБД Apache Derby. Общая методика их реализации отражает общие правила проектирования:

первоначально создается локальный вариант решения задачи, предполагающий будущее разделение на клиентскую и серверную части; такими части реализованы в архивах notepad.jar и example12.jar;

решение этой задачи средствами технологии CORBA представлена архивами orbpadserver.jar и orbpadclient.jar;

решение этой задачи средствами технологии CORBA представлена архивами rmibpadserver.jar и rmipadclient.jar.

150

Рисунок 3.25 — Запуск RMI-клиента из архива rmipadclient.jar

Рисунок 3.26 — Сравнительные размеры созданных Jar-архивов приложений