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í.

Lekce 6 - Java RMI - Příklad s CMD přes LAN, MAN, WAN

V minulé lekci kurzu o RMI v Javě, Java RMI - Spuštění RMI Server/Klient přes CMD, jsme obsluhovali naši aplikaci z příkazového řádku.

V dnešní lekci si vyzkoušíme sdílení základních datových typů přes síť LAN.

Příklad s CMD přes LAN, MAN, WAN

Vytvoříme RMI klienta a server v IDE. Spuštění provedeme přímo přes příkazový řádek a to jak RMI registru, tak serveru i klienta. Využijeme defaultní port (port 1099), ale tentokrát si to vyzkoušíme na místní LAN. LAN je standardně několik PC spojených Wi-fi, nad kterou dohlíží router. Celá sít jede na TCP/IP ve formátu IPv4. Systém přidělování IP adres je DHCP a IP adresy klientů jsou rozsahu 192.168.2.101 - 192.168.2.120. Mohl bych ji nastavit na plný rozsah sítě typu C od 192.168.2.0 do 192.168.2.255, ale protože se jedná o domácí sít, není potřeba tolik IP adres. Jak si všimnete, tak server RMI běží na IP: 192.168.2.101 a klient poběží na 192.168.2.102.

V našem případě se samozřejmě nemusíme omezovat pouze na IP adresy v rámci LAN. Pokud bychom server spustili na počítači s veřejnou IP adresou do internetu (tzv. WAN), pak stačí nastavit klientovi IP adresu serveru na internetu a vše by mělo fungovat také. Tedy za předpokladu, že z klienta budete schopni dosáhnout připojení na IP daného RMI serveru. V některých případech to bývá zablokováno na routeru nebo firewallem na LAN, kde běží klient.

Osnova dnešní lekce bude následující:

  • Naprogramujeme si rozhraní pro sdílené objekty, které budeme přes RMI sdílet
  • Naprogramujeme serverovou část
  • Naprogramujeme klientskou část
  • Zkompilujeme, zbuildujeme a vyexportujeme projekty
  • Spustíme RMI registry, RMI server, RMI klienta a zkontrolujeme výstupy

1) Programování rozhraní pro sdílené objekty

Jako první krok si vytvoříme Java SE projekt pro RMI server. Do tohoto projektu si vytvoříme rozhraní, které bude dědit od java.rmi.Remote. Do rozhraní si vložíme 4 metody. První bude opět typu void pro kontrolní výpis. Zbývající budou mít návratové typy a parametry v hlavičkách. Druhá metoda přijme string, provede úpravu stringu na serveru a upravený string pošle zpět na klienta. Třetí i čtvrtá toto provedou s primitivními datovými typy boolean a byte.

package rozhrani;
public interface RozhraniRMI04 extends java.rmi.Remote {
    public void zavolejVOID() throws java.rmi.RemoteException;
    public String ziskejString(String s) throws java.rmi.RemoteException;
    public boolean ziskejBoolean(boolean bool) throws java.rmi.RemoteException;
    public byte ziskejUpravByte(byte bajt) throws java.rmi.RemoteException;
}

Opětovně si všimněte throws java.rmi.Remo­teException u metod, které mají být sdíleny.

Rozhraní RMI objektu - RMI - Remote Method Invocation

2) Programování serverové části

Nejdříve si vytvoříme sdílený objekt (ObjektRMI.java), který dědí od java.rmi.server­.UnicastRemote­Object a zároveň implementuje naše navržené rozhraní rozhrani.Rozhra­niRMI04. Pouze vyplníme těla metod. Dělají to, co jsme si definovali na začátku, když jsme tvořili dané rozhraní. Novinkou je pouze přidání proměnné třídy, která bude uchovávat počet zavolání metod.

package server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ObjektRMI extends UnicastRemoteObject implements rozhrani.RozhraniRMI04 {

    private static final long serialVersionUID = 1L;
    private int hodnota=0;

    protected ObjektRMI() throws RemoteException {
        super();
    }

    public void zavolejVOID() throws RemoteException {
        hodnota++;
        System.out.println("Pocet volani metod na serveru :\t"+hodnota);
    }

    public String ziskejString(String s) throws RemoteException {
        hodnota++;
        System.out.println("Z klienta dorazil tento retezec : "+s);
        return "Upravime retezec na serveru "+s;
    }

    public boolean ziskejBoolean(boolean bool) throws RemoteException {
        hodnota++;
        System.out.println("Z klienta dorazil tento boolean : "+bool);
        return !bool;
    }

    public byte ziskejUpravByte(byte bajt) throws RemoteException {
        hodnota++;
        System.out.println("Z klienta dorazil tento byte(bajt) :"+bajt);
        return (byte)((byte) bajt+8);
    }
}
Java RMI Objekt - RMI - Remote Method Invocation

Jako další krok provedeme vytvoření třídy RMI serveru (ServerRMI.java). Kód je velmi jednoduchý. Nejdříve vyrobíme instanci RMIServeru. Poté zavoláme inicializační metodu, která ma za úkol vytvořit sdílený objekt. No a poté již provedeme pouze nahrání (sdílený, zaregistrování) sdíleného RMI objektu do RMI registrů pod nějakým názvem (identifikátorem). Naším identifikátorem bude String "SdilenyObjek­t04".

Jediná změna oproti předchozím příkladům je to, že neprovádíme binding (zaregistrování) přes objekt rozhraní registrů java.rmi.regis­try.Registry, ale nyní to provádíme přes jmennou službu java.rmi.Naming. Prakticky je skoro jedno jakou možnost si vyberete, fungují obě.

package server;
import java.net.*;
import java.rmi.*;
public class ServerRMI {
    private ObjektRMI sdilObjekt;
    private void initSdilenyObjekt(){
        try {
            sdilObjekt = new ObjektRMI();
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se vytvorit sdileny objekt");
            e.printStackTrace();
        }
    }

    private void sdilejObjektRMI(){
        try {
            Naming.bind("SdilenyObjekt04",sdilObjekt);
        } catch (MalformedURLException | RemoteException | AlreadyBoundException e) {
            System.out.println("Nepodarilo se nahrat(zaregistrovat RMI objekt v rmiregistrech)");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ServerRMI serverRMI = new ServerRMI();
        serverRMI.initSdilenyObjekt();
        serverRMI.sdilejObjektRMI();
        System.out.println("RMI Server ceka ...");
    }
}
Java RMI Server - RMI - Remote Method Invocation

3) Programování klientské části

Nyní nás samozřejmě čeká klientská část. Pokud jste si naprogramovali a úspěšně spustili předchozí příklady, tak jste si museli všimnout, že je koncept klienta prakticky stále stejný. Klientovi je nutné opět zajistit přístup k rozhraní (CTRL+C a CTRL+V) z projektu serveru do projektu klienta. Pak si samozřejmě vytvoříme obyčejnou spouštěcí třídu s public static void main(String args) metodou. V této třídě opět zavoláme Naming třídu s metodou lookup(), kde parametr bude URL složené z IP adresy, portu na kterém běží RMI registry a identifikátoru sdíleného objektu. Správná syntaxe URL pro RMI našeho příkladu je následující: rmi://21.15.45.33:1099/SdilenyObjekt04. V obecné definici je to rmi://IPv4:port/identifikátor. Jakmile se nám podaří získat sdílený objekt, již si jen zavoláme jeho metody.

package klient;
import java.net.*;
import java.rmi.*;
import java.util.Scanner;
import rozhrani.RozhraniRMI04;

public class KlientRMI {
    private RozhraniRMI04 stubRMI;

    private void ziskameSdilenyObjekt(String s,int port) {
        //  format "rmi://21.15.45.33:1099/SdilenyObjekt04"
        String lanString = "rmi://"+s+":"+port+"/SdilenyObjekt04";
        try {
            stubRMI = (RozhraniRMI04) Naming.lookup(lanString);
        } catch (MalformedURLException | RemoteException | NotBoundException e) {
            System.out.println("Nepodarilo se ziskat sdileny RMI objekt");
            e.printStackTrace();
        }
    }

    private void zavolameSdileneMetody(Scanner key) {
        try {
            stubRMI.zavolejVOID();
            System.out.print("Vlozte String : ");
            String s = key.nextLine();
            System.out.println("Zde je upraveny string ze serveru : "+ stubRMI.ziskejString(s));
            boolean b = false;
            System.out.println("Zde je inverzi Boolean : "+stubRMI.ziskejBoolean(b));
            byte bajt = (byte) 58;
            System.out.println("Zde je upraveny byte : "+stubRMI.ziskejUpravByte(bajt));
            stubRMI.zavolejVOID();
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se zavolat sdilene metody");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println("Start RMI Klienta");
        KlientRMI klient = new KlientRMI();
        Scanner key = new Scanner(System.in);
        System.out.print("Zadejte IPv4 ve formatu napr. 45.112.35.55 a stisknete Enter :");
        String s = key.nextLine();
        klient.ziskameSdilenyObjekt(s,1099);
        klient.zavolameSdileneMetody(key);
        System.out.println("Konec RMI Klienta");
    }
}
Java RMI klient - RMI - Remote Method Invocation

4 Kompilace, buildování a export projektů

Nyní provedeme zkompilování a případně i spuštění. Samozřejmě, pokud nejsou spuštěné RMI registry s nastavením spouštěného projektu, tak aplikace při spuštění v konzoli vyvolá výjimky. Podstatné je, že je to zkompilované a máme vytvořenou spouštěcí konfiguraci a poté provedeme export. Export projektu je ukázán v předchozí kapitole.

5) Spuštění RMI registru, RMI serveru, RMI klienta a kontrola výstupů

Nyní si spustíme na PC, kde máme v plánu spustit RMI server, příkazový řádek a vyvoláme výpis "ipconfig -all". Tento výpis nám ukáže IP adresu našeho PC v síti. Samozřejmě způsobů jak zjisti IP adresu je celá řada. V našem případě je IP adresa počítače, na kterém poběží server: 162.168.2.101.

IP server - RMI - Remote Method Invocation

Zajisté jste si všimli, že export jsem provedl přímo do rootu disku e:\ . Jako první před spuštěním serveru je nutno zajistit přístup ke zkompilové třídě rozhraní našeho serveru. Toho docílíme tím, že nakopírujeme *.class zkompilované rozhraní na úroveň disku e:\. Lze to krásně vidět při výpisu "dir rozhrani". Výpisy "dir" jsou pro přehled struktury. Poté spustíme RMI registry "start rmiregistry".

Nyní spustíme RMI server. Toho docílíme příkazem "java -jar RMIServer04.jar server.ServerRMI". Pokud existuje zkompilované rozhraní, ke kterému má spuštěný *.jar přístup, spuštění proběhne v pořádku. Pokud neexistuje, výpis vyvolá výjimku.

Spuštění Java RMI serveru - RMI - Remote Method Invocation

Nyní nás čeká spuštění RMI klienta. Opět jsme provedli spuštění příkazového řádku a zadali "ipconfig -all" . Jak vidíte, IP adresa počítače, na kterém poběží klient, je 162.168.2.102. Nyní spustíme RMI klienta příkazem "java -jar RMIKlient04.jar klient.KlientRMI" . Výpis na konzole ukazuje spuštění klienta a získání součtu ze serveru.

Spuštění Java RMI klienta - RMI - Remote Method Invocation

Přesuneme se na PC, kde běží RMI server. Dle konzolového výpisu komunikace mezi klientem/serverem proběhla perfektně a bez chyb.

Výsledek RMI serveru - RMI - Remote Method Invocation

Pro jistotu spustíme klienta ještě jednou.

Spustíme Java RMI klienta - RMI - Remote Method Invocation

A opětovně vidíme, že server umožnil zavolání sdílených metod. Samozřejmě nám souhlasí i počet zavolání. Každý klient provedl 5 volání, spuštěni 2 klienti, takže je to celkem 10 volání.

Výsledek RMI Server druhý klient - RMI - Remote Method Invocation

V příštím díle, Java RMI - Pole primitivních datových typů, si vytvoříme příklad na pole primitivních datových typů.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 428x (12.29 kB)

 

Předchozí článek
Java RMI - Spuštění RMI Server/Klient přes CMD
Všechny články v sekci
RMI - Remote Method Invocation
Přeskočit článek
(nedoporučujeme)
Java RMI - Pole primitivních datových typů
Článek pro vás napsal Robert Michalovič
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
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