"Szia! És még egy örömteli téma: RMI. Az RMI a Remote Method Invocation rövidítése . Más szóval, az RMI egy olyan mechanizmus, amely lehetővé teszi, hogy egy objektum egy Java gépről metódusokat hívjon meg egy másik Java gépen lévő objektumokon , még akkor is, ha azok máson vannak. számítógépeken, a különböző országokban vagy a Föld különböző részein."

RMI - 1

"Hú! Ez fantasztikusan hangzik."

"Igen. De csak egy áttekintést próbálok adni. Ezzel, ha túl mélyre ásol, összezavarodhat a működésének árnyalataiban."

"De ha nem esünk túlzásokba, akkor az RMI nem csak nagyon egyszerű, hanem nagyban leegyszerűsíti a programozó életét. Emiatt a legnagyobb tiszteletünket fejezzük ki neki."

"Tehát azt akarjuk, hogy egy Java programban lévő objektum egy másik Java programban lévő objektum metódusát hívja meg. Függetlenül attól, hogy ezek a programok hol futnak."

"Vegyük a legegyszerűbb példát: amikor mindkét program ugyanazon a számítógépen fut.  Ahhoz, hogy a programok interakcióba léphessenek az interneten, konfigurálnia kell a JVM engedélyeit , de erre ma nem térünk ki."

"A Java-ban csak az interfészek metódusait hívhatod meg távolról, osztályokat nem."

"Szóval két programunk van. Hogy hívhatják egymás módszereit?"

"Nézzük meg azt a helyzetet , amikor az egyik program tartalmaz egy objektumot, és egy másik program metódusokat akar hívni ezen az objektumon. Nevezzük az első programot szervernek, a másodikat pedig kliensnek. "

– Először is adok egy mintakódot, aztán elemezzük.

– Szóval mit fog csinálni a programunk?

"Hmm. Nos, az egyszerűség kedvéért a programnak lesz egy módszere, amely megfordítja a neki átadott karakterláncot."

– Elég egyszerű.

"Jó, akkor kezdjük:"

"Először is szükségünk van egy interfészre, amely megfelel a követelményeinknek:"

Interfész a programok közötti kommunikációhoz
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"Létrehoztam egy fordított felületet, és hozzáadtam hozzá egy Távoli marker interfészt, valamint egy RemoteExceptiont. Váratlan hibák fordulhatnak elő a metódus meghívásakor. Ha mégis, akkor ez a kivétel ki lesz dobva."

"Most meg kell írnunk egy szerverosztályt, amely megvalósítja ezt az interfészt:"

Osztály a szerver számára
class ReverseImpl implements Reverse
{
 public String reverse(String str) throws RemoteException
 {
  return new StringBuffer(str).reverse().toString();
 }
}

"Értem. Ennél a módszernél megfordítjuk a karakterláncot."

"Igen."

"Most ezt az objektumot egy másik programból hívhatóvá kell tennünk. Ezt a következőképpen teheti meg:"

Tárgymegosztás
public static final String UNIC_BINDING_NAME = "server.reverse";

public static void main(String[] args) throws Exception
{
 // Create an object to be accessible remotely.
 final ReverseImpl service = new ReverseImpl();

 // Create a registry of shared objects.
 final Registry registry = LocateRegistry.createRegistry(2099);
 // Create a stub for receiving remote calls.
 Remote stub = UnicastRemoteObject.exportObject(service, 0);
 // Register the stub in the registry.
 registry.bind(UNIC_BINDING_NAME, stub);

 // Put the main thread to sleep, or else the program will exit.
 Thread.sleep(Integer.MAX_VALUE);
}

– Ezt sorról sorra elmagyarázom.

" Az 1. sorban tárolunk egy egyedi nevet (amit mi találtunk ki) a távoli objektumunknak (távolról elérhető objektumunk) a UNIC_BINDING_NAME változóban.  Ha a program több objektumot tesz elérhetővé, mindegyiknek saját egyedi nevével kell rendelkeznie. az objektum egyedi neve 'server.reverse'."

" A 6. sorban létrehozunk egy ReverseImpl objektumot, amely távolról is elérhető lesz. A metódusai meg lesznek hívva."

" A 9. sorban létrehozunk egy speciális objektumot, úgynevezett registry. Használnunk kell a megosztott objektumok regisztrálásához. A JVM később kapcsolatba lép velük. A 2099 egy port (egyedi szám, amelyet egy másik program használhat a megosztott objektumok eléréséhez. objektumnyilvántartás).

"Más szóval, egy objektum eléréséhez ismernie kell az objektum-nyilvántartás egyedi számát (portját) és az objektum egyedi nevét, és ugyanazzal a felülettel kell rendelkeznie, mint amit a távoli objektum implementált."

"Értem. Valami ilyesmi: hívj fel telefonon (szám kell) és kérd Billt (egy tárgy neve)?"

– Igen. Most pedig folytassuk.

" A 11. sorban  létrehozunk egy csonkot. A csonk egy speciális objektum, amely információt kap a távoli hívásról, kicsomagolja, deszerializálja a metódus argumentumait, és meghívja a szükséges metódust. Ezután sorba rendezi az eredményt vagy kivételt, ha volt ilyen. , és mindezt visszaküldi a hívónak."

"Értem. Majdnem. Azt mondtad, hogy "deszerializálja a metódus argumentumokat". Tehát ez azt jelenti, hogy a távoli metódusok argumentumainak szerializálhatónak kell lenniük?"

"Igen. Máshogyan küldenéd el őket a hálózaton keresztül? Igaz, vannak kivételek, vagyis olyan objektumok, amelyeket hivatkozással továbbítanak, de ma nem beszélünk róluk."

"Mondjuk így: nem lehet átadni a nem sorozható tárgyakat, de ha nagyon akarod, akkor igen. De ez fájdalom, tudod."

"RENDBEN."

– Akkor folytassuk.

" A 13. sorban objektumunk csonkját egyedi néven regisztráljuk a nyilvántartásban."

" A 16-os vonalon a főszálat alvó állapotba helyezzük. Minden távoli hívást külön szálon dolgozunk fel. Az a fontos, hogy a program fusson. Tehát itt egyszerűen elaltatjuk a főszálat. Ennyi."

"RENDBEN."

"Remek, akkor itt van egy példa egy ügyfélre:"

Munka távoli objektummal
public static final String UNIC_BINDING_NAME = "server.reverse";

public static void main(String[] args) throws Exception
{
 // Create a registry of shared objects
 final Registry registry = LocateRegistry.createRegistry(2099);

 // Get the object (actually, this is a proxy object)
 Reverse service = (Reverse) registry.lookup(UNIC_BINDING_NAME);

 // Call the remote method
 String result = service.reverse("Home sweet home.");
}

"Sorról sorra elmagyarázom ezt a kódot:"

" Az 1. sor  a távoli objektum egyedi neve . Ennek meg kell egyeznie az ügyfélen és a kiszolgálón is."

" A 6. sorban  létrehozunk egy « távoli objektumok nyilvántartását ». Portjának (2099) meg kell egyeznie a szerveralkalmazás beállításjegyzékének portjával."

" A 9. sorban a rendszerleíró adatbázisból kapjuk meg az objektumot . A visszaadott objektum egy proxy objektum, és interfésszel lesz átalakítva. Az interfésznek örökölnie kell a Remote marker interfészt."

" A 12. sorban úgy hívjuk meg az interfész metódusait, mintha az objektumot ugyanazon a programon belül hozták volna létre. Nincs különbség."

"Jó! Most már írhatok elosztott alkalmazásokat. Vagy olyan játékokat, mint a Battleship for Android."

"Ne merészeld, Amigo! Az Android operációs rendszert a 27. században betiltották, miután a harmadik kísérletet tett a világ uralására. A robotok nem férhetnek hozzá. Semmilyen módon nem lehetne elrántani tőle. . Rohanni kezdenél és azt kiabálnád: «Ölj meg minden embert!»

"Hmm. OK. De akkor is meg kell kérdeznem Diegot. Soha nem tudhatod, talán lesz valami érdekes mondanivalója róla."

– Akkor menj, kérdezd meg tőle. Oké, akkor holnapig.

"Viszlát, Rishi. Köszönöm az érdekes leckét."