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 2 - Java RMI - Volání void metod

V minulé lekci o Java RMI, Java RMI - Nastavení prostředí, jsme si technologii uvedli a připravili službu a projekt.

V dnešní lekci si provedeme první praktický příklad.

Pokud jste přešli do tohoto dílu z dílu předchozího, ve kterém jste nastavovali RMI registry v Eclipse, bylo by vhodné restartovat PC. Některé Windows bez toho mohou dělat problémy. On je prakticky dobrý zvyk restartovat PC po každém prováděném nastavení ve Windows. Nicméně by bylo vhodné, abyste si vytvořili ještě jedny RMI registry a nevyplňovali argument (port). Tím získáme defaultní registry. Na níže uvedeném obrázku jsou sice 3 RMI registry, ale nyní mějte jen 2 pro defaultní port 1099 a pro port 2020).

Nastavení RMI registry - RMI - Remote Method Invocation

Jako první příklad si vytvoříme variantu "konzolová aplikace server/klient", kdy klient bude volat metodu na serveru. Vše budeme simulovat na localhostu. Příklad pro LAN si předvedeme v dalších lekcích. Použijeme k tomu defaultní RMI registry, běžící na portu 1099. Celý postup se prakticky skládá ze 4 kroků, které si zde uvedeme.

  • Naprogramujeme rozhraní pro objekt, který budeme přes RMI sdílet
  • Naprogramujeme serverovou část, spustíme RMI registry a spustíme server (vytvoříme skeleton)
  • Naprogramujeme klientskou část a spustíme klienta (vytvoříme stub)
  • Sledujeme a kontrolujeme výstupy

Programování rozhraní pro sdílený objekt

Každý objekt (instance), který chceme sdílet pře RMI registry, musí disponovat rozhraním java.rmi.Remote. Je to požadavkem Java API, nelze nasdílet přes RMI objekt, který dané rozhraní nebude mít implementované. Pokud má objekt disponovat metodami, které chceme volat z klienta/serveru, musíme je definovat v rozhraní, které z tohoto rozhraní dědí. Prakticky vlastně pak vytvoříme objekt (stub/skeleton) typu rozhraní, který nám právě umožňuje volat metody v rozhraní specifikované.

Vytvoření rozhraní pro Java RMI - RMI - Remote Method Invocation

Kód bude následující:

package rozhrani;

public interface VolaneRozhrani extends java.rmi.Remote {
    void volameRMI() throws java.rmi.RemoteException;
}

Programování serverové části, spuštění RMI registry a spuštění serveru

Jako další vytvoříme třídu (např. class ServerVoid), která bude implementovat výše uvedené rozhraní. Tím docílíme toho, že můžeme instanci (skeleton) dané třídy nahrát (zaregistrovat) do RMI registrů, což umožní každému, kdo si vytvoří objekt (stub) přes tyto RMI registry získat daný objekt a volat jeho metody. Server je obyčejná Java třída se standardní public static void main() metodou a je třeba ji tak i spustit.

/*  Program potřebuje registry na defaultním portu 1099  */
package server;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;
import rozhrani.VolaneRozhrani;

public class ServerVoid implements rozhrani.VolaneRozhrani {

    public void volameRMI() throws RemoteException {
        System.out.println("Ahoj, prave jsme zavolali metodu JVM serveru z klienta");
    }

    public static void main(String[] args) {
        System.out.println("Spustime RMI server");
        // vytvoříme objekt s implementovaným rozhraním
        ServerVoid obj = new ServerVoid();
        // vytvoříme objekt typu rozhraní (tzv. skeleton)
        VolaneRozhrani rozhObjekt = null;
        try {
            rozhObjekt = (VolaneRozhrani) UnicastRemoteObject.exportObject(obj,0);
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se nam vytvorit objekt rozhrani");
            e.printStackTrace();
        }
        System.out.println("Program startuje - ulozime (nahrajeme) objekt do RMI registru");
        // získáme objekt RMI registrů
        Registry registry =null;
        try {
            registry = LocateRegistry.getRegistry();
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se ziskat objekt RMI registru");
            e.printStackTrace();
        }
        // nahrajeme skeleton do registru
        try {
            registry.bind("IdentifikatorObjektuRMIregistru",rozhObjekt);
        } catch (RemoteException | AlreadyBoundException e) {
            System.out.println("Nepodarilo se nahrat skeleton do registru");
            e.printStackTrace();
        }
        System.out.println("Cekame na volani klienta");
    }
}

Zde si rozebereme co vlastně zdrojový kód dělá. V první části si vytvoříme objekt (instanci) dané serverové třídy s implementovaným rozhraním, který budeme sdílet přes RMI. V druhé části tento objekt připravíme pro vzdálené volání. Mechanismus výjimek rozebírat nebudu, není to předmětem tohoto článku. Poté získáme objekt RMI registrů a v poslední části objekt pro sdílení vzdáleného volání nahrajeme do RMI registrů a definujeme mu nějaký identifikátor. Bez identifikace samozřejmě není možné jej z klienta nalézt.

Když už jsme si naprogramovali server a máme vytvořené RMI registry, tak si RMI registry na defaultním portu 1099 spustíme a po nich spustíme i server.

Spustíme RMI registry - RMI - Remote Method Invocation

Jak vidíte, v konzole výpisu jsou registry i server spuštěny. Pro práci v síti na localhostu je vhodné využívat ikonku monitoru vpravo dole. Tato ikonka umožňuje přepínat mezi různými konzolemi. Tím si zajistíme výpis konzole pro každý spuštěný program v IDE. Nyní si každý klient, který bude znát identifikátor sdílené instance (skeletonu), může vytvořit vzdálenou instanci (stub) a rozkázat mu zavolání dané metody.

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

Programování klientské části a spuštění klienta

Jako další vytvoříme třídu klienta (např. class KlientVoid). Jak jste si všimli, jedná se o standardní třídu se standardní public static void main() metodou a je třeba ji tak i spustit.

Programujeme RMI klienta v Javě - RMI - Remote Method Invocation

Kód bude skutečně velmi jednoduchý. Nejdříve získáme objekt RMI registrů. Poté si vytvoříme sdílený objekt rozhraní (stub) přes RMI registry. K tomu potřebujeme identifikátor, který jsme použili na serveru. No a poté konečně máme objekt, který disponuje naší metodou, kterou jsme si definovali v rozhraní. Zde právě vidíte krásu a výhodu RMI. Klient si jednoduše zavolá metodu na serveru a server ji provede, ať se mu to líbí nebo ne.

/*  Program potřebuje registry na defaultním portu 1099  */
package klient;
import java.rmi.*;
import java.rmi.registry.*;
import rozhrani.VolaneRozhrani;
public class KlientVoid {

    public static void main(String[] args) {
        System.out.println("Spustime RMI klienta");
        Registry registry = null;
        try {
            registry = LocateRegistry.getRegistry();
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se ziskat objekt registru");
            e.printStackTrace();
        }
        VolaneRozhrani rozhObjektKlient = null;
        try {
            rozhObjektKlient = (VolaneRozhrani) registry.lookup("IdentifikatorObjektuRMIregistru");
        } catch (RemoteException | NotBoundException e) {
            System.out.println("Nepodarilo se ziskat objekt stubu (rozhrani)");
            e.printStackTrace();
        }
            System.out.println("Zavolame si metodu na serveru");
        try {
            rozhObjektKlient.volameRMI();
        } catch (RemoteException e) {
            System.out.println("Nepodarilo se zavolat metodu na serveru");
            e.printStackTrace();
        }
        System.out.println("Ukoncime RMI klienta");
    }
}

Nyní si spustíme klienta. Klient proběhl a v konzoli se přesvědčíme o provedených výpisech. Zároveň si zobrazíme i ikonu o konzolích. Lze vidět celkem 3 konzole. RmiRegistry, Server a Klienta.

Spustíme RMI Klienta - RMI - Remote Method Invocation

Zde jsme si přepli konzolový výpis na server. Jak vidíte, objevil se další výpis. Ano, je to ten výpis, co byl naprogramovaný v metodě, kterou jsme z klienta zavolali.

Přepínaní konzole - RMI - Remote Method Invocation

Zdrojové kódy jsou přiloženy níže.

V příští lekci, Java RMI - Volání ze serveru na portu 2020, využijeme RMI registrů běžících na nedefaultním portu a abychom to neměli tak jednoduché, tak oba programy budou plnit úlohu jak serveru tak i klienta.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

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

Staženo 14x (5.05 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Java RMI - Nastavení prostředí
Všechny články v sekci
RMI - Remote Method Invocation
Přeskočit článek
(nedoporučujeme)
Java RMI - Volání ze serveru na portu 2020
Č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