"Hei! Og enda et gledelig emne: RMI. RMI står for Remote Method Invocation . Med andre ord er RMI en mekanisme som lar et objekt fra en Java-maskin kalle metoder på objekter fra en annen Java-maskin , selv om de er på forskjellige datamaskiner, i forskjellige land eller på forskjellige sider av kloden."

RMI - 1

"Wow! Det høres fantastisk ut."

"Jepp. Men jeg skal bare prøve å gi deg en oversikt. Med dette, hvis du graver for dypt, kan du bli forvirret av nyansene i hvordan det fungerer."

"Men hvis du ikke går til ekstremer, så er RMI ikke bare veldig enkelt, men det forenkler også en programmerers liv i stor grad. Dette gir vi den vår dypeste respekt."

"Så vi vil at ett objekt i et Java-program skal kalle en metode på et objekt som er i et annet Java-program. Uansett hvor disse programmene kjører."

"La oss vurdere det enkleste eksemplet: når begge programmene kjører på samme datamaskin.  For å tillate programmer å samhandle over Internett, må du konfigurere JVMs tillatelser , men vi vil ikke dekke det i dag."

"I Java kan du eksternt kalle bare metodene for grensesnitt, ikke klasser."

"Så, vi har to programmer. Hvordan kan de kalle hverandres metoder?"

"La oss vurdere situasjonen der ett program inneholder et objekt, og et annet program ønsker å kalle metoder på det objektet. La oss kalle det første programmet serveren, og det andre - klienten. "

"Først skal jeg gi en prøvekode, og så analyserer vi den."

"Så hva vil programmet vårt gjøre?"

"Hmm. Vel, for enkelhets skyld vil programmet ha en metode som reverserer en streng som sendes til den."

"Enkelt nok."

"Bra, la oss begynne:"

"For det første trenger vi et grensesnitt som vil tilfredsstille kravene våre:"

Grensesnitt for kommunikasjon mellom programmer
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"Jeg opprettet et Reverse-grensesnitt og la til et Remote Marker-grensesnitt til det, samt et RemoteException. Uventede feil kan oppstå når metoden kalles. Hvis noen gjør det, vil dette unntaket bli kastet."

"Nå må vi skrive en serverklasse som implementerer dette grensesnittet:"

Klasse for serveren
class ReverseImpl implements Reverse
{
 public String reverse(String str) throws RemoteException
 {
  return new StringBuffer(str).reverse().toString();
 }
}

"Jeg skjønner. Vi snur strengen i denne metoden."

"Japp."

"Nå må vi gjøre dette objektet anropbart fra et annet program. Slik gjør du det:"

Objektdeling
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);
}

"Jeg skal forklare dette linje for linje."

" I linje 1 lagrer vi et unikt navn (som vi har laget) for vårt eksterne objekt (objekt som er eksternt tilgjengelig) i UNIC_BINDING_NAME -variabelen.  Hvis programmet gjør flere objekter tilgjengelige, må hver ha sitt eget unike navn. objektets unike navn er 'server.reverse'."

" På linje 6 lager vi et ReverseImpl- objekt som vil være eksternt tilgjengelig. Metodene vil bli påkalt."

" På linje 9 lager vi et spesielt objekt kalt et register. Vi må bruke det til å registrere objektene vi deler. JVM vil samhandle med dem senere. 2099 er en port (et unikt nummer som et annet program kan bruke for å få tilgang til vår objektregister)."

"Med andre ord, for å få tilgang til et objekt, må du kjenne objektregisterets unike nummer (port) og objektets unike navn, og ha samme grensesnitt som det som er implementert av det eksterne objektet."

"Jeg skjønner. Noe sånt som: ring på telefon (trenger et nummer) og spør etter Bill (navnet på et objekt)?"

"Ja. Nå, la oss fortsette."

" På linje 11  lager vi en stubb. En stubb er et spesielt objekt som mottar informasjon om det eksterne anropet, pakker det ut, deserialiserer metodeargumentene og kaller den nødvendige metoden. Deretter serialiserer den resultatet eller unntaket, hvis det var en , og sender alt tilbake til den som ringer."

"Jeg skjønner. Nesten. Du sa at det 'deserialiserer metodeargumentene'. Så det betyr at de eksterne metodenes argumenter må være serialiserbare?"

"Ja. Hvordan ville du ellers sendt dem over nettverket? Riktignok finnes det unntak, dvs. objekter som sendes ved referanse, men vi skal ikke snakke om dem i dag."

"Vi vil si det slik: du kan ikke passere ikke-serialiserbare objekter, men hvis du virkelig vil, så kan du det. Men det er en smerte, vet du."

"OK."

"Så la oss fortsette."

" På linje 13 registrerer vi objektets stubb under et unikt navn i registeret."

" På linje 16 legger vi hovedtråden i dvale. Alle eksterne samtaler behandles i separate tråder. Det viktige er at programmet kjører. Så vi legger rett og slett hovedtråden i dvale her. Det er det."

"OK."

"Flott, så her er et eksempel på en klient:"

Arbeide med et eksternt objekt
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.");
}

"Jeg skal forklare denne koden linje for linje:"

" Linje 1  er det eksterne objektets unike navn . Dette må være det samme på både klienten og serveren."

" I linje 6  oppretter vi et « register over eksterne objekter ». Porten (2099) må være den samme som porten til registeret for serverapplikasjonen."

" På linje 9 henter vi objektet fra registeret. Det returnerte objektet er et proxy-objekt og konverteres til et grensesnitt. Grensesnittet må arve Remote Marker-grensesnittet."

" På linje 12 kaller vi grensesnittets metoder som om objektet ble opprettet i samme program. Det er ingen forskjell."

"Kult! Nå kan jeg skrive distribuerte applikasjoner. Eller spill som Battleship for Android."

"Ikke tør du, Amigo! Android-operativsystemet ble forbudt på 2600-tallet etter det tredje forsøket på å ta over verden. Roboter har ingen tilgang til det overhodet. Det ville ikke være noen måte å trekke deg vekk fra det Du begynte å løpe rundt og rope: «Drep alle menneskene!»

"Hmm. OK. Men jeg må fortsatt spørre Diego. Du vet aldri, kanskje han har noe interessant å si om det."

"Så gå og spør ham. Ok, vel, til i morgen."

"Bye, Rishi. Takk for den interessante leksjonen."