"Hej! Og endnu et glædeligt emne: RMI. RMI står for Remote Method Invocation . Med andre ord er RMI en mekanisme, der tillader et objekt fra en Java-maskine at kalde metoder på objekter fra en anden Java-maskine , selvom de er på forskellige computere, i forskellige lande eller på forskellige sider af kloden."

RMI - 1

"Wow! Det lyder fantastisk."

"Jep. Men jeg vil kun forsøge at give dig et overblik. Med dette, hvis du graver for dybt, kan du blive forvirret over nuancerne i, hvordan det fungerer."

"Men hvis du ikke går til ekstremer, så er RMI ikke kun meget simpelt, men det forenkler også en programmørs liv i høj grad. Det giver vi den vores dybeste respekt."

"Så vi vil have et objekt i et Java-program til at kalde en metode på et objekt, der er i et andet Java-program. Uanset hvor disse programmer kører."

"Lad os overveje det enkleste eksempel: når begge programmer kører på den samme computer.  For at tillade programmer at interagere over internettet, skal du konfigurere JVM'ens tilladelser , men det dækker vi ikke i dag."

"I Java kan du kun eksternt kalde grænseflademetoderne, ikke klasser."

"Så vi har to programmer. Hvordan kan de kalde hinandens metoder?"

"Lad os overveje situationen , hvor et program indeholder et objekt, og et andet program ønsker at kalde metoder på det objekt. Lad os kalde det første program for serveren, og det andet - klienten. "

"Først giver jeg noget prøvekode, og så analyserer vi det."

"Så hvad vil vores program gøre?"

"Hmm. Nå, for nemheds skyld vil programmet have en metode, der vender en streng, der sendes til den."

"Simpelt nok."

"Godt, så lad os starte:"

"For det første har vi brug for en grænseflade, der vil tilfredsstille vores krav:"

Interface til kommunikation mellem programmer
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"Jeg oprettede en Reverse-grænseflade og tilføjede en Remote-markør-grænseflade til den, såvel som en RemoteException. Uventede fejl kan opstå, når metoden kaldes. Hvis nogen gør det, vil denne undtagelse blive kastet."

"Nu skal vi skrive en serverklasse, der implementerer denne grænseflade:"

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

"Jeg kan se. Vi vender strengen i denne metode."

"Ja."

"Nu skal vi gøre dette objekt kaldet fra et andet program. Sådan gø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 vil forklare det her linje for linje."

" I linje 1 gemmer vi et unikt navn (som vi har lavet) for vores fjernobjekt (objekt, der er fjerntilgængeligt) i variablen UNIC_BINDING_NAME.  Hvis programmet gør flere objekter tilgængelige, skal hver have sit eget unikke navn. Vores objektets unikke navn er 'server.reverse'."

" På linje 6 opretter vi et ReverseImpl- objekt, som vil være tilgængeligt eksternt. Dets metoder vil blive påberåbt."

" På linje 9 opretter vi et særligt objekt kaldet et register. Vi skal bruge det til at registrere de objekter, vi deler. JVM'en vil interagere med dem senere. 2099 er en port (et unikt nummer, som et andet program kan bruge til at få adgang til vores objektregister)."

"Med andre ord, for at få adgang til et objekt skal du kende objektregistrets unikke nummer (port) og objektets unikke navn og have den samme grænseflade som den, der er implementeret af fjernobjektet."

"Jeg kan se. Noget som: ring på telefon (brug for et nummer) og spørg efter Bill (navnet på en genstand)?"

"Ja. Lad os nu fortsætte."

" På linje 11  opretter vi en stub. En stub er et specielt objekt, der modtager information om fjernkaldet, pakker det ud, deserialiserer metodeargumenterne og kalder den påkrævede metode. Derefter serialiserer den resultatet eller undtagelsen, hvis der var en , og sender det hele tilbage til den, der ringer."

"Jeg forstår. Næsten. Du sagde, at det 'deserialiserer metodeargumenterne'. Så det betyder, at fjernmetodernes argumenter skal kunne serialiseres?"

"Ja. Hvordan ville du ellers sende dem over netværket? Sandt nok er der undtagelser, dvs. objekter, der videregives ved reference, men vi vil ikke tale om dem i dag."

"Vi vil sige det sådan: du kan ikke passere ikke-serialiserbare genstande, men hvis du virkelig vil, så kan du det. Men det er en smerte, du ved."

"OKAY."

"Så lad os fortsætte."

" På linje 13 registrerer vi vores objekts stub under et unikt navn i registreringsdatabasen."

" På linje 16 sætter vi hovedtråden i dvale. Alle fjernopkald behandles på separate tråde. Det vigtige er, at programmet kører. Så vi sætter simpelthen hovedtråden i dvale her. Det er det."

"OKAY."

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

Arbejde 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 vil forklare denne kode linje for linje:"

" Linje 1  er fjernobjektets unikke navn . Dette skal være det samme på både klienten og serveren."

" I linje 6  opretter vi et " registrering af fjernobjekter ". Dens port (2099) skal være den samme som porten til registreringsdatabasen for serverapplikationen."

" På linje 9 henter vi objektet fra registreringsdatabasen. Det returnerede objekt er et proxyobjekt og konverteres til et interface. Interfacet skal arve Remote Marker-grænsefladen."

" På linje 12 kalder vi grænsefladens metoder, som om objektet blev oprettet i det samme program. Der er ingen forskel."

"Fedt! Nu kan jeg skrive distribuerede applikationer. Eller spil som Battleship til Android."

"Tør du ikke, Amigo! Android-operativsystemet blev forbudt i det 27. århundrede efter dets tredje forsøg på at overtage verden. Robotter har ingen som helst adgang til det. Der ville ikke være nogen måde at trække dig væk fra det Du ville begynde at løbe rundt og råbe: «Dræb alle mennesker!»

"Hmm. OK. Men jeg bliver stadig nødt til at spørge Diego. Man ved aldrig, måske har han noget interessant at sige om det."

"Så spørg ham. Okay, ja, indtil i morgen."

"Bye, Rishi. Tak for den interessante lektion."