Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
175
Добавлен:
17.04.2018
Размер:
255.49 Кб
Скачать

ЛАБОРАТОРНАЯ РАБОТА №8

По курсу «Интернет-программирование»

Работа с удаленными объектами по технологии RMI Java

Цель работы.

Ознакомиться с технологией RMI.

Приобретаемые компетенции:

  1. Понимание принципов создания интернет-приложений c использованием технологий удаленного вызова методов

  2. Организация вызова удаленного метода для решения практической задачи

  1. Принципы технологии RMI Java

    1. RMI

RMI (Remote Method Invocation) — технология удаленного использования Java объектов для организации распределенных систем на базе сети компьютеров-узлов.

Пусть на удаленном компьютере есть метод Calculate, который для обработки получает объект пользовательского типа DateMassiv и после обработки возвращает объект пользовательского типа Result.

Тогда имеем следующую схему работы:

При вызове удаленных методов сервера клиентом вызывается (локально) метод класса-заглушки (stubs). Клиент не хранит копии вызываемых объектов сервера, а хранит ссылки на объекты-заглушки.

Метод класса заглушки производит:

  • Развертывание параметров (marshalling)‏

  • Передачу данных на сервер

  • Объект получатель выполняет:

  • Свертывание параметров

  • Поиск вызыванного объекта

  • Вызов данного метода

  • Извлечение возвращаемого значения или исключения

  • Передачу пакета клиенту

Типы удаленных объектов (на сервере) описываются на клиенте в виде интерфейса.

Листинг 1. Описание интерфейса с двумя методами: getData и makeCalculate

package miet;

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface RMI extends Remote {

public String getData(String text) throws RemoteException;

public Result makeCalculate(BigData bd) throws RemoteException;

}

Поскольку интерфейс удаленных объектов потребуются как на клиенте, так и на сервере,

удобно делать интерфейс клиента в виде jar-архива, который загружается и на клиент и сервер.

Для удаленных объектов удобно делать интерфейс в виде jar-архива, который загружается и на клиент и сервер. Тогда, в случае обновления, собирается один новый jar и устанавливается на всех серверах и клиентах

Если удаленные объекты используют пользовательские типы данных (классы) то их также целесообразно описывать отдельно и импортировать в клиент, сервер и интерфейс.

Для иллюстрации работы RMI рассмотрим пример, разработанный в среде NetBeance. Идея примера: посылаем в удаленный метод объект, выполняем обработку, получаем в качестве ответа другой объект.

Пример содержит:

JavaMietLib – проект с библиотекой общих кастомных классов

RMIInterfase – проект с классами общих интерфейсов

RMIClient – проект с классами клиента

RMIServer – проект с классами сервера

Листинг 2. Класс интерфесов RMIInterface содержит объявления методов

package miet;

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface RMI extends Remote {

//Обявлем простой метод возвращающий строку

public String getData(String text) throws RemoteException;

//Обявлем метод принимающий и возвращающий кастомный объект

public Result makeCalculate(BigData bd) throws RemoteException;

}

Пользовательских объектов в примере два: BigData и Result (см. Листинг 2). Опишем их в отдельном проекте JavaMietLib. Класс BigData хранит в себе коллекцию ArrayList, которая будет заполняться вещественными числами (float). Класс Result будет содержать сумму этих чисел во внутренней переменной Supremum, значение которой будет рассчитано в удаленном методе makeCalculate, которому будет передан объект BigData.

Листинг 3. Класс BigData

package miet;

import java.io.Serializable;

import java.util.ArrayList;

public class BigData implements Serializable {

//класс BigData будет содержать коллекцию ArrayList

private ArrayList data;

public void BigData( ArrayList temp ) {

this.data = temp;

}

public ArrayList getdata() {

return this.data;

}

public void setdata(ArrayList temp ) {

this.data = temp;

}

}

Листинг 4. Класс Result.

package miet;

import java.io.Serializable;

public class Result implements Serializable {

/*

класс Result будет хранить число типа float,

которое является результатом некоего расчета

*/

private float Supremum;

public float getSupremum() {

return this.Supremum;

}

public void setSupremum(float temp) {

this.Supremum = temp;

}

}

Клиент для работы с RMI в самом простом виде состоит из одного класса, реализующего метод main. Логично выделять метод работы с сервером отдельно и вызывать его в main. В примере этот метод называется connectServer().

Метод connectServer должен:

  1. Подключиться к серверу

  2. Войти в нужное пространство имен

  3. Вызвать нужный метод в пространстве имен

В листинге 5 эти операции выделены жирным шрифтом.

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

Поскольку и клиент и сервер в рамках нашего теста находятся на одной машине, IP адрес определяем как 127.0.0.1. Порт указываем 1099 (может быть любым не занятым) и такой-же порт надо будет указать в соответствующем месте класса сервера. Перед вызовом удаленного объекта makeCalculate cоздаем, передаваемый в него, объект BigData и заполняем его данными.

Листинг 5. Класс RMIClient.

package miet;

import java.rmi.registry.LocateRegistry;

import java.rmi.registry.Registry;

import java.util.ArrayList;

public class RMIClient {

public static void main(String args[]) {

RMIClient client = new RMIClient(); //создаем экземпляр самого себя

System.out.println("Client created");

client.connectServer(); //вызываем метод работы с сервером

}

private void connectServer() {

try {

//1. Подключение к серверу

//получить ссылку на реестр удаленного объекта начальной

//загрузки на определенном узле (включая локальный узел)

Registry reg = LocateRegistry.getRegistry("127.0.0.1", 1099);

//2. Входим в нужное пространство имен

//создаем экземпляр объекта класса - заглушки

//с удаленного сервера MIETServer

RMI rmi = (RMI) reg.lookup("MIETServer");

System.out.println("Connect to server");

//Создаем объект BigData и заполняем его данными

ArrayList temp = new ArrayList();

temp.add(1.0F); temp.add(2.0F); temp.add(3.0F);

BigData bd = new BigData();

bd.setdata(temp);

System.out.println("--------------------------------------");

//3. Вызываем нужный метод в пространстве имен

Result rr = rmi.makeCalculate(bd); //выполняем метод на удал. объекте

System.out.println(rr.getSupremum()); //печатаем результат - 6

} catch(Exception e) { System.out.println(e); }

}

После разработки класса, разрабатываем класс сервера, который будет содержать (имплеминтировать) методы, к которым будут удаленно обращаться клиенты: getData и makeCalculate. Метод main сервера содержит регистрацию нашего сервера на веб-сервере в соответствующем пространстве имен, совпадающим с пространством имен клиента т.е. — MIETServer см. Листинг 6.

Листинг 6. Класс RMIServer.

package miet;

import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry;

import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject;

import java.util.ArrayList; import miet.Result;

public class RMIServerImpl extends UnicastRemoteObject implements RMI {

public RMIServerImpl() throws RemoteException{ super(); }

public static void main(String args[]) {

try {

//Создает и экспортирует Registry экземпляр на локальном узле,

который принимает запросы на указанном port.

Registry reg = LocateRegistry.createRegistry(1099);

//Привязываем класс RMIServerImpl к имени MIETServer

reg.rebind("MIETServer", new RMIServerImpl());

System.out.println("Server started");

} catch(Exception e) {

System.out.println(e);

}

}

//Определяем метод getData

public String getData(String text) throws RemoteException {

text = "Stsrt "+text;

return text;

}

//Определяем метод makeCalculate

public Result makeCalculate(miet.BigData bd) throws RemoteException {

ArrayList bdArray = bd.getdata();

float suprm = 0;

Result r = new Result();

for(int i=0; i<bdArray.size(); i++) {

suprm += (float) bdArray.get(i);

}

r.setSupremum(suprm);

return r;

}

}

После разработки примера сначала запускаем сервер, а затем клиент, см рис. 1.

Рис. 1. Выполнение удаленных методов по технологии RMI

Задание на лабораторную работу

  1. Реализовать работу удаленного метода по технологии RMI в соответствии с вариантом (при затруднении смотреть опорный пример из папки soft, файл rmi.zip)

  2. Варианты:

1

Реализовать удаленный метод поиска наибольшего, наименьшего и среднего значений в коллекции содержащей вещественные числа. Длина коллекции до 1000 элементов. Коллекцию сформировать генератором случайных чисел. Тип коллекции — на усмотрение студента. Коллекцию передавать, а результат получать в виде объектов пользовательских классов.

2

Реализовать удаленный метод сортировки по возрастанию коллекции содержащей строки. Длина коллекции до 100 элементов. Коллекцию сформировать генератором случайных чисел. Тип коллекции — на усмотрение студента. Коллекцию передавать, а результат получать в виде объектов пользовательских классов.

3

Реализовать удаленный метод решения квадратного уравнения. Условие уравнения передавать, а результат получать в виде объектов пользовательских классов.

Контрольные вопросы:

  1. Что означает RMI?

  2. Как работает технология RMI?

  3. Что такое пространство имен в RMI?

  4. Какие действия нужно выполнить, чтобы создать клиента?

  5. Какие действия нужно выполнить, чтобы создать сервер?

  6. Какие действия нужно выполнить, чтобы клиенту подключиться к серверу?

  7. Какие действия нужно выполнить, чтобы сервер смог принимать запросы клиента?

  8. Почему методы RMI описываются в виде интерфейса?

  9. Как с помощью RMI организовать выполнение распределенных вычислений?

  10. Какие задачи могут и не могут быть эффективно выполнены с помощью распределенных вычислений?

Соседние файлы в папке Интернет технологии