Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

3. diel - Java RMI - Volanie zo servera na porte 2020

V minulej lekcii kurzu o RMI v Jave sme si zavolali vzdialenú metódu na serveri. V dnešnej lekcii si vyskúšame použitie nedefaultního portu. V našom prípade použijeme RMI registre na porte 2020. Prakticky sa jedná o RMI registre, ktoré sme si vytvorili v dieli nastavenie prostredia. Avšak pozor, je nutné nezabudnúť, že RMI registre nastavujeme pre daný projekt (Working directory). Inak bude aplikácia padať. V tomto príklade bude mať každá trieda (server aj klient) používajúce RMI ako svoj skeleton tak i stub toho druhého.

Nastavíme RMI registre na port 2020 - RMI - Remote Method Invocation

Tento príklad teda bude podobný príkladu v predchádzajúcej lekcii, avšak využijeme iný port pre RMI registre, vyskúšame si volanie zo servera na klienta / z klienta na server. Opäť sa bude jednať o konzolovú aplikáciu koncepte server / klient. Všetko budeme simulovať na localhost. Celý postup sa prakticky opäť skladá zo 4 krokov, ktoré si tu uvedieme.

  • Naprogramujeme si rozhranie pre zdieľané objekty, ktoré budeme cez RMI zdieľať
  • Naprogramujeme serverovú časť, spustíme RMI registre a spustíme server
  • Naprogramujeme klientskú časť a spustíme klienta
  • Sledujeme a kontrolujeme výstupy

Programovanie rozhranie pre zdieľané objekty

Opätovne naprogramujeme rozhranie, ktoré bude zdedené od rozhrania java.rmi.Remote. Klient musí implementovať dve metódy a server iba jednu.

Vytvoríme rozhranie poděděné od Remote - RMI - Remote Method Invocation

Rozhranie pre klienta:

package rozhrani.klient;

public interface RozhraniKlient extends java.rmi.Remote {
    void volameKlientMetoda1() throws java.rmi.RemoteException;
    void volameKlientMetoda2() throws java.rmi.RemoteException;
}

Rozhranie pre server:

package rozhrani.server;

public interface RozhraniServer extends java.rmi.Remote {
    void volameServerMetoda1() throws java.rmi.RemoteException;
}

Programovanie serverovej časti, spustenie RMI registre a spustenie servera

Opätovne si naprogramujeme server (napr. Class ServerRMI), ktorý bude implementovať zdieľané rozhranie, ktoré sme napísali vyššie. Z implementovaného rozhrania nám vznikla povinnosť doprogramovať vnútro jedinej metódy "volameServer­Metoda1 ()". Zdrojový kód serveru som napísal bez importov, môžete si ich dodať a kód tak zjednodušiť.

/*  Program potřebuje registry na defaultním portu 2020  */
package server;

public class ServerRMI implements rozhrani.server.RozhraniServer {
    private static rozhrani.server.RozhraniServer rozhrServer = null;
    private static java.rmi.registry.Registry registry = null;

    public void volameServerMetoda1() throws java.rmi.RemoteException {
        System.out.println("Metoda zavolana na serveru");
        try {
            Thread.sleep(5000); // uspíme vlákno na 5 sekund
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Zavolame metody na klientovi");
        rozhrani.klient.RozhraniKlient rozhObjektKlient= null;
        try {
            rozhObjektKlient = (rozhrani.klient.RozhraniKlient) registry.lookup("KlientRMI");
        } catch (java.rmi.RemoteException | java.rmi.NotBoundException e) {
            System.out.println("Nepodarilo se ziskat objekt stubu (rozhrani)");
            e.printStackTrace();
        }
        System.out.println("Zavolame si metody na klientech");
        try {
            rozhObjektKlient.volameKlientMetoda1();
            rozhObjektKlient.volameKlientMetoda2();
        } catch (java.rmi.RemoteException e) {
            System.out.println("Nepodarilo se zavolat metodu na klientovi");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println("Spustime RMI server");
        // vytvoříme objekt rozhraní (tzv. skeleton)
        try {
            rozhrServer = (rozhrani.server.RozhraniServer) java.rmi.server.UnicastRemoteObject.exportObject(new ServerRMI(),0);
        } catch (java.rmi.RemoteException e) {
            System.out.println("Nepodarilo se nam vytvorit skeleton");
            e.printStackTrace();
        }
        // získáme objekt RMI registru pro daný port
        try {
            registry = java.rmi.registry.LocateRegistry.getRegistry(2020);
        } catch (java.rmi.RemoteException e) {
            System.out.println("Nepodarilo se ziskat objekt RMI registru");
            e.printStackTrace();
        }
        // nahrajeme skeleton do registru
        try {
            registry.bind("ServerRMI",rozhrServer);
        } catch (java.rmi.RemoteException | java.rmi.AlreadyBoundException e) {
            System.out.println("Nepodarilo se nahrat skeleton do registru");
            e.printStackTrace();
        }
        System.out.println("Cekame na volani Klienta");
    }
}

Tu si rozoberieme čo vlastne zdrojový kód robí. V prvej časti (public static void main () metóde) si vytvoríme objekt (inštanciu) triedy implementujúce zdieľané rozhrania. Potom získame objekt RMI registra a už len nahráme zdieľaný objekt do RMI registrov. Týmto spôsobíme vznik tzv. Skeleton. Skeleton pomenujeme, presnejšie mu priradíme identifikátor, "ServerRMI". Samozrejme meno identifikátora je voliteľné a takých Skeleton môžeme nahrať do RMI registrov koľko chceme. Nie som si vedomý obmedzenia čo sa týka počtu nahraných skeleton. Zaiste ste si všimli, že metóda získanie RMI registrov má tentoraz parameter 2020. Áno, tento parameter špecifikuje port (viac pozri Java dokumentácia). Teoreticky by sme mohli aj vyskúšať spustiť viac RMI registrov na rôznych portoch a do nich nahrať inej SKELETON, ale čo z toho? Fungovať by to najskôr malo. Metóda volameServerMetoda1 () je metódou, ktorá je k dispozícii stub na klientovi. Pokiaľ ju zavolá, potom v metóde vytvoríme stub klienta a tým získame metódy, ktoré má zdieľaný objekt na klientovi k dispozícii.

RMI Java server - RMI - Remote Method Invocation

Tu si celý kód ukážeme v IDE. V druhej časti (volameServer­Metoda1 () metóde) sa vykoná najskôr uspanie na 5 sekúnd, potom si vytvoríme zrkadlový objekt Stube klienta a zavoláme obe jeho metódy, ktoré sú (budú) na klientovi k dispozícii. Oneskorenie 5 sekúnd je tam len aby ste prepli výpis konzoly v IDE a mohli sa presvedčiť o výpisu na klientovi na vlastné oči.

Zaiste ste si všimli, že kód je navrhnutý tak, že sa spustí server, potom klient, klient zavolá metódu na serveri a v nej sa zas zavolajú metódy na klientovi. Samozrejme, mohol som to urobiť na priamo bez tej zdieľané metódy na serveri, kedy server priamo vytvorí stub klienta, ale chcel som, aby sme si to vyskúšali.

Server RMI Java komplet - RMI - Remote Method Invocation

Programovanie klientskej časti a uspania klienta

Ako ďalšie vytvoríme triedu klienta (napr. Class KlientRMI). Ako ste si všimli, ide o štandardnú public static void main () metódu a je potrebné ju tak aj spustiť.

RMI Klient - RMI - Remote Method Invocation

Kód je skutočne veľmi jednoduchý a je veľmi analogický s tým zo servera. Najskôr vytvoríme skeleton klienta, získame RMI registre z portu 2020 a potom skeleton nahráme s identifikátorom "KlientRMI" do RMI registra. Po tomto je skeleton klienta k dispozícii všetkým, ktorí disponujú rozhraním.

Ďalej vytvoríme zdieľaný objekt rozhrania servera (tzv. Stub) cez RMI registre. K tomu potrebujeme identifikátor, ktorý sme použili na serveri v RMI registroch. No a potom konečne máme objekt, ktorý disponuje našou metódou, ktorú sme si definovali v rozhraní.

package klient;
import java.rmi.*;
import java.rmi.registry.*;
import rozhrani.klient.*;
import rozhrani.server.*;

public class KlientRMI implements RozhraniKlient {
    private static RozhraniKlient rozhrKlient;

    public void volameKlientMetoda1() throws RemoteException {
        System.out.println("Klient RMI metoda1");
    }

    public void volameKlientMetoda2() throws RemoteException {
        System.out.println("Klient RMI metoda2");
    }

    public static void main(String[] args) {
        System.out.println("Spustime RMI klienta");
        // vytvoříme objekt implementující rozhraní (tzv. skeleton)
        try {
            rozhrKlient = (RozhraniKlient) java.rmi.server.UnicastRemoteObject.exportObject(new KlientRMI(),0);
        } catch (java.rmi.RemoteException e) {
            System.out.println("Nepodarilo se nam vytvorit skeleton");
            e.printStackTrace();
        }
        // získáme objekt RMI registru pro daný port
        Registry registry = null;
        try {
            registry = LocateRegistry.getRegistry(2020);    }
        catch (RemoteException e) {
            System.out.println("Nepodarilo se ziskat objekt registru");
            e.printStackTrace();
        }
        // nahrajeme stub do registru
        try {
            registry.bind("KlientRMI",rozhrKlient);
        } catch (java.rmi.RemoteException | java.rmi.AlreadyBoundException e) {
            System.out.println("Nepodarilo se nahrat stub do registru");
            e.printStackTrace();
        }
        // zavoláme metodu na serveru
        RozhraniServer rozhObjektServer = null;
        try {
            rozhObjektServer = (RozhraniServer) registry.lookup("ServerRMI");
        } catch (RemoteException | NotBoundException e) {
            System.out.println("Nepodarilo se ziskat objekt stubu (rozhrani)");
            e.printStackTrace();
        }
        System.out.println("Zavolame si metodu na serveru");
        try {
            rozhObjektServer.volameServerMetoda1();
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se zavolat metodu na serveru");
            e.printStackTrace();
        }
        System.out.println("Cekame na volani Serveru");
    }
}

Teraz si spustíme opätovne RMI registre na porte 2020.

RMI registre spustíme - RMI - Remote Method Invocation

Spustíme aj server a pozrieme si výpis na konzole.

RMI server spustíme - RMI - Remote Method Invocation

Teraz si spustíme klienta a pozrieme si výpis na konzole. Prepneme na server a pozrieme sa na výpis konzole.

RMI klient spustíme - RMI - Remote Method Invocation

No a teraz sa zas prepneme sa na výpis konzole klienta. Krásne ide vidieť zavolané metódy na klientovi.

RMI výsledok - RMI - Remote Method Invocation

V budúcom dieli si preberieme trochu ďalšie teórie ohľadom RMI.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 7x (6.65 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Java RMI - Volanie void metód
Všetky články v sekcii
RMI - Remote Method Invocation
Preskočiť článok
(neodporúčame)
Java RMI - Vysvetlenie pojmov a opis tried
Článok pre vás napísal Robert Michalovič
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Programuji převážně v Javě SE,EE a trochu nativním C a CUDA. více viz.https://cz.linkedin.com/in/robert-michalovic
Aktivity