Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> JINI, пример использования 
:(
    Опции темы
Samotnik
Дата 4.5.2008, 04:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: нет
Всего: 191



Jini – это название распределенной вычислительной среды, которая может предложить принцип «network plug and play». Устройство или программная служба может быть подключена к сети, может известить о своем присутствии, и клиенты, желающие использовать такой сервис, могут разместить его для дальнейших вызовов. Jini также можно использовать для мобильных вычислительных задач, когда сервис подключается в сеть на короткое время.
Технология Jini™ – это сервис-ориентированная архитектура, которая определяет программную модель, испоьзующую и расширяющую технологию Java ™ с целью построения безопасных распределенных систем, состоящих из федераций сетевых сервисов и клиентов. 
Подробнее, можно прочесть на официальном сайте
Для создания простого приложения, необходимо:
1) jini  smile  как не странно 
2) jdk (я использую 1.5.0_12) (можно скачать с http://www.java.sun.com)
3) (не обязательное условие)  IDE  -  IntelliJ IDEA 7.0.1
К проекту необходимо подключить jdk,  два .jar  файла  jsk-lib.jar и  jsk-platform.jar (их нужно взять в папочке jini2_1\lib\)
Итак, приложение будет предоставлять информацию по различным туристическим направлениям (в виде направление/количество дней/цена тура/вид транспорта), а также позволять ее добавлять, удалять и редактировать по направлениям. 
Итак, начнем:
Клиент и реализация сервиса должны разделять некоторые общие классы. Для нашего задания общими классами будут класс, определяющий хранение информации TourInfo  и интерфейс сервиса TourInfoService.
Если сервис выполняется удаленно и запускается на отдельной JVM, то объект TourInfo должен быть сериализован для транспортировки на клиентскую машину, реализуя интерфейс Serializable
Определим класс TourInfo, который представляет совокупность данных по одному направлению. В классе реализованы метод добавления (сеттер) и взятия (геттер) информации. Она представлена в виде массива. 
Код

package common;

import java.util.ArrayList;
import java.io.Serializable;
/**
 * класс базы данных турфирмы
 * info - | направление | цена | количество дней | вид тура |
 * records - совокупность информации (info) по разным направлениям
 */
public class TourInfo implements Serializable {
    private ArrayList info;

    public TourInfo() {
    }

    public ArrayList getInfo() {
        return info;
    }

    public void setInfo(ArrayList info) {
        this.info = info;
    }
}

Если мы желаем сделать сервис TourInfoService,  доступным по сети, наилучшим выходом будет отделить реализацию от интерфейса. Затем сделать интерфейс доступным с клиента и загружать реализацию со службы поиска.
Определим интерфейс нашего сервиса – TourInfoService, куда запишем объявления методов, которые будут реализовывать сервис.
Код

package common;

import java.rmi.RemoteException;
import java.util.ArrayList;

/**
 * сервис по работе с информацией о турах представлен
 * в виде Jini-сервиса
 */

public interface TourInfoService {
    // получение информации
    public ArrayList getTourInfo() throws RemoteException;
    // добавление нового тура
    public void addTourInfo(String dir,int price,int days,String type)
                throws RemoteException;
    // удаление тура по существующему направлению
    public void delTourInfo(String direction) throws RemoteException;
    // редактирование тура по данному направлению
    public void editTourInfo(String direction,String dir, int price, 
           int days, String type) throws RemoteException;
}

Все методы интерфейса выбрасывают java.rmi.RemoteException на случай сетевой ошибки (потерянное соединение, несуществующий сервер, незагружаемый класс и т.д.).
  - Компиляция общих классов.    
  - Компиляция совершенно обычна, не используются никакие опции.
javac src/common/*.java

                                                         Клиент
Создадим две версии клиента – для одноадресного и многоадресного поиска. Клиентов будем создавать в пакете(папке) client.
Одноадресный клиент(Unicast Client)
Если имеется известный локатор сервиса, который нет необходимости искать, то клиент использует одноадресный механизм.
Код

package client;

import net.jini.core.discovery.LookupLocator;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
import common.TourInfoService;

import java.net.MalformedURLException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class UnicastTourInfoService {

    LookupLocator lookup = null;
    ServiceRegistrar registrar = null;
    TourInfoService  infoService = null;


    public UnicastTourInfoService(){

// подготовка к обнаружению
        try {
            lookup = new LookupLocator("jini://127.0.0.1");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        System.setSecurityManager(new RMISecurityManager());
// обнаружение службы поиска

/*клиент получает регистратор от JVM локатора сервиса.  Локатор выполняет ServiceRegistrar, используя реализацию, которая неизвестна ни клиентам, ни дургим сервисам. Классы-реализаторы содержатся в reggie-dl.jar и загружаются клиентам и сервисам из HTTP сервера */

        try {
            registrar = lookup.getRegistrar();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
// подготовка шаблона для поиска в службе
        Class[] classes = new Class[] {TourInfoService.class};
        ServiceTemplate template =
                   new ServiceTemplate(null,classes,null);
//  ищем наш Jini-сервис
        try {
            infoService = (TourInfoService) registrar.lookup(template);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        if (infoService == null){
            System.out.println("info service null");
            System.exit(2);
        }
//  запускаем меню, а вместе с ним и всю логику
        menu();
    }

    private void menu() {

        BufferedReader br =
                 new BufferedReader(new InputStreamReader(System.in));
        int option=1;
        while (true){
            System.out.println("**************************");
            System.out.println("\t1-Добавить ");
            System.out.println("\t\t| направление | цена |"
                                   "+ количество дней | вид тура |");
            System.out.println("\t2-Удалить (по направлению)");
            System.out.println("\t3-Редактировать (по направлению)");
            System.out.println("\t4-Просмотреть");
            System.out.println("\t5-Выход");
            System.out.println("**************************");
            String line="5";

            try {
                line = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            option = Integer.parseInt(line);
            switch(option){
                case 1:
                    try {
                        System.out.println("Направление: ");
                        String d = br.readLine();
                        System.out.println("Цена: ");
                        String pr = br.readLine();
                        int price = Integer.parseInt(pr);
                        System.out.println("Количество дней: ");
                        String days = br.readLine();
                        int day = Integer.parseInt(days);
                        System.out.println("Тип тура: ");
                        String tp = br.readLine();
// вызов метода сервиса для добавления
                        infoService.addTourInfo(d,price,day,tp);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace;                  }
                    break;
                case 2:
                    try {
                        String dest = br.readLine();
// вызов метода сервиса для удаления 
                        infoService.delTourInfo(dest);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                case 3:
                    try {
                        System.out.println("Направление: ");
                        String dest = br.readLine();
                        System.out.println("Новое направление: ");
                        String d = br.readLine();
                        System.out.println("Новая цена: ");
                        String pr = br.readLine();
                        int price = Integer.parseInt(pr);
                        System.out.println("Новое количество дней: ");
                        String days = br.readLine();
                        int day = Integer.parseInt(days);
                        System.out.println("Новый тип тура: ");
                        String tp = br.readLine();

// вызов метода сервиса для редактирования
                       infoService.editTourInfo(dest, d, price, day, tp);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                case 4:
                    try {
// вызов метода сервиса для просмотра
                        ArrayList records = infoService.getTourInfo();
                        for (int i=0;i<records.size();i++){
                            ArrayList inf = (ArrayList)records.get(i);
                            for (int j=0; j<inf.size(); j++)
                                System.out.print(inf.get(j)+" ");
                            System.out.println();
                         }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                case 5:
                    System.exit(0);
                    break;
            }
        }
    }

    public static void main(String[] args) {
        new UnicastTourInfoService();
    }
}

Компиляция клиента. 
Клиент использует ряд Jini-классов. Эти классы нужно указать в CLASSPATH компилятора.

set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH="D:\work\jini\turizm\src;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar"
javac -classpath %CLASSPATH% src/client/*.java
    
   где пути необходимо поменять на свои.

                                          Многоадресный клиент (Multicast Client)
Более вероятно, что клиенту понадобится искать по всем локаторам сервиса, пока не найдет искомый. Для этого используется многоадресный поиск. Клиенту не нужен пользовательский поток, чтобы остаться существующим достаточное время для поиска локаторов сервиса и нахождения подходящего сервиса. Поэтому в функции main() пользовательский потом «засыпает» на короткий период (10 секунд).
Код

package client;
import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.discovery.LookupDiscovery;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
import common.TourInfoService;

import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

public class MulticastTourInfoService implements DiscoveryListener {

    TourInfoService infoService = null;

    public MulticastTourInfoService(){
        System.setSecurityManager(new RMISecurityManager());
        LookupDiscovery discover = null;
        try {
            discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        discover.addDiscoveryListener(this);
    }
    public void discovered(DiscoveryEvent discoveryEvent) {
        ServiceRegistrar[] registrars = discoveryEvent.getRegistrars();
        Class[] classes = new Class[] {TourInfoService.class};
        ServiceTemplate template =
                        new ServiceTemplate(null,classes,null);

        for (int n=0; n<registrars.length; n++){
            System.out.println("Найдена служба LookUp");
            ServiceRegistrar registrar = registrars[n];
            try {
                infoService =
                       (TourInfoService) registrar.lookup(template);
            } catch (RemoteException e) {
                e.printStackTrace();
                continue;
            }
            if (infoService == null){
                System.out.println("infoService null");
                continue;
            }

            menu();
        }
    }

    public void discarded(DiscoveryEvent discoveryEvent) {
            }

    private void menu() {
        //  метод такой же как и в одноадресном клиенте (копируем оттуда).
    }

    public static void main(String[] args) {
       
        new MulticastTourInfoService();
        try {
            Thread.currentThread().sleep(100000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

             Компиляция клиента. 
Клиент использует ряд Jini-классов. Эти классы нужно указать в CLASSPATH компилятора.
set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH="D:\work\jini\turizm\src;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar"
javac -classpath %CLASSPATH% src/client/*.java

где пути необходимо поменять на свои.
                                     Загрузка сервиса полностью
    Сервис не использует какое-либо конкретное свойство хоста – он не зависим ни от оборудования, ни от операционной системы. В таком случае возможна загрузка сервиса целиком на клиент и запуск его там. Сервис является прокси.

                       Реализация сервиса – файл TourInfoService.java в пакете complete.
Код

ackage complete;

// использует общие файлы
import common.TourInfoService;
import common.TourInfo;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;

public class TourInfoServiceImpl implements TourInfoService, Serializable {

    public TourInfo tourInfo = new TourInfo();
    public ArrayList records = new ArrayList();

    // получение информации
    public ArrayList getTourInfo() throws RemoteException {
        return records;
    }

    // добавление нового тура
    public void addTourInfo(String dir, int price, int days, String type) 
                                                 throws RemoteException {
        ArrayList al = new ArrayList();

        al.add(dir);
        al.add(price);
        al.add(days);
        al.add(type);

       tourInfo.setInfo(al);
       records.add(tourInfo.getInfo());
    }

    // удаление тура по существующему направлению
    public void delTourInfo(String direction) throws RemoteException {

        for (int i=0;i<records.size();i++){
            ArrayList inf = (ArrayList)records.get(i);
            if (inf.get(0).equals(direction)) records.remove(i);
        }
    }

    // редактирование тура по данному направлению
    public void editTourInfo(String direction,String dir, int price,
                       int days, String type)  throws RemoteException {

         for (int i=0;i<records.size();i++){
            ArrayList inf = (ArrayList)records.get(i);
                if (inf.get(0).equals(direction)){
                    inf.set(0,dir);
                    inf.set(1,price);
                    inf.set(2,days);
                    inf.set(3,type);
                }            
        }
    }
}

Компиляция реализации сервиса.
set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH="D:\work\jini\turizm\src;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar"
javac -classpath %CLASSPATH% src/complete/*.java
где пути меняем на свои.
                                                            Сервер
Помещается в пакет complete.
Сервис-провайдеру необходимо создать экземпляр экспортируемого объекта сервиса, зарегистрировать его и поддерживать аренду в жизнеспособном состоянии (alive). В методе discovered() он не только регистрирует сервис, но также и добавляет его в LeaseRenewalManager для поддержания вечной (FOREVER) аренды. Это менеджер запускает свои собственные потоки для перерегистрации аренды, эти потоки являются демонами (т.е. фоновые процессы). Поэтому в методе main() пользовательский поток «засыпает» на столько, на сколько мы хотим, чтобы действовал сервер (server to stay around). Заметьте, что если сервер завершает работу, то аренда больше не сможет возобновляться (renew).
serviceID первоначально равняется null. Как только служба поиска назначит ID сервиса, он сохраняется в файле  FileClassifier.id. Если сервер падает, то при рестарте он восстанавливает ID и использует.
Код

package complete;

import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.discovery.LookupDiscovery;
import net.jini.lease.LeaseListener;
import net.jini.lease.LeaseRenewalEvent;
import net.jini.lease.LeaseRenewalManager;
import net.jini.core.lookup.ServiceID;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceRegistration;
import net.jini.core.lease.Lease;

import java.io.*;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;

public class TourInfoServiceServer implements DiscoveryListener,
                                                    LeaseListener {

    protected LeaseRenewalManager leaseManager = new                            LeaseRenewalManager();
    protected ServiceID serviceID = null;
    protected TourInfoServiceImpl impl;

    public static void main(String[] args) {

        TourInfoServiceServer s = new TourInfoServiceServer();
        Object keepAlive = new Object();
        synchronized(keepAlive){
            try {
                keepAlive.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public TourInfoServiceServer() {
        impl = new TourInfoServiceImpl();
        DataInputStream din = null;
        try {
           din = new DataInputStream(new                                               FileInputStream("TourInfoService.id"));
            serviceID = new ServiceID(din);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.setSecurityManager(new RMISecurityManager());
        LookupDiscovery discover = null;
        try {
            discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        discover.addDiscoveryListener(this);
    }

    public void discovered(DiscoveryEvent discoveryEvent) {
        ServiceRegistrar[] registrars = discoveryEvent.getRegistrars();
        for (int n=0; n<registrars.length; n++){
            ServiceRegistrar registrar = registrars[n];
            ServiceItem item = new ServiceItem(serviceID,impl,null);
            ServiceRegistration reg;
            try {
               reg = registrar.register(item, Lease.FOREVER);
               //  reg = registrar.register(item, 20000);
            } catch (RemoteException e) {
                e.printStackTrace();
                continue;
            }
            System.out.println("--------------------------------------");
            System.out.println("Service is registered with ID="+
                                        reg.getServiceID());
            System.out.println("--------------------------------------");

            leaseManager.renewUntil(reg.getLease(),Lease.FOREVER,this);
            //leaseManager.renewUntil(reg.getLease(),20000,this);

            if (serviceID == null){
                serviceID = reg.getServiceID();
                DataOutputStream dout = null;
                try {
                    dout = new DataOutputStream(new
                           FileOutputStream("TourInfoService.id"));
                    serviceID.writeBytes(dout);
                    dout.flush();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void discarded(DiscoveryEvent discoveryEvent) {

    }

    public void notify(LeaseRenewalEvent leaseRenewalEvent) {
        System.out.println("Leasing is expired "+
                                       leaseRenewalEvent.toString());
    }
}

Компиляция сервера
set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH="D:\work\jini\turizm\src;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar"
javac -classpath %CLASSPATH% src/complete/*.java


                                                      запуск проекта:
1)создадим jar файл с именем TourInfoService-dl.jar
cd src
jar cf TourInfoServiceImpl-dl.jar common/TourInfo.class common/TourInfoService.class complete/TourInfoServiceImpl.class
2)поместим его в папку lib-dl внутри директории с Jini.
3)Запустим jini2_1\installverify\Launch-All.lnk
4)Запустим сервер:
cd src
title Server
set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH=".;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar" 
java -Djava.rmi.server.codebase=http://xata:8081/TourInfoServiceImpl-dl.jar -Djava.security.policy=policy.all complete.TourInfoServiceServer
5)Запустим клиента.
    Одноадресного:
    cd src
title Unicast client
set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH=".;D:\work\jini\turizm\src;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar" 
java -classpath %CLASSPATH% -Djava.security.policy=policy.all client.UnicastTourInfoService

    Или многоадресного:
cd src
title Multicast Client
set JINI_HOME=D:\work\jini2_1\lib
set CLASSPATH=".;D:\work\jini\turizm\src;%JINI_HOME%\jsk-platform.jar;%JINI_HOME%\jsk-lib.jar" 
java -classpath %CLASSPATH% -Djava.security.policy=policy.all client.MulticastTourInfoService


Все  smile   готово, буду рад, если этот материал кому - нибудь пригодится  smile 

Это сообщение отредактировал(а) Samotnik - 4.5.2008, 04:14
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0671 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.