"Hej! Och ytterligare ett roligt ämne: RMI. RMI står för Remote Method Invocation. Med andra ord är RMI en mekanism som gör att ett objekt från en Java-maskin kan anropa metoder på objekt från en annan Java-maskin, även om de är på olika datorer, i olika länder eller på olika sidor av världen."

RMI - 1

"Wow! Det låter fantastiskt."

"Japp. Men jag ska bara försöka ge dig en överblick. Med detta, om du gräver för djupt, kan du bli förvirrad av nyanserna i hur det fungerar."

"Men om du inte går till ytterligheter så är RMI inte bara väldigt enkelt, utan det förenklar också en programmerares liv avsevärt. För vilket vi visar den vår djupaste respekt."

"Så vi vill att ett objekt i ett Java-program ska anropa en metod på ett objekt som finns i ett annat Java-program. Oavsett var dessa program körs."

"Låt oss betrakta det enklaste exemplet: när båda programmen körs på samma dator.  För att tillåta program att interagera över Internet måste du konfigurera JVM:s behörigheter, men vi kommer inte att täcka det idag."

"I Java kan du fjärranropa endast metoderna för gränssnitt, inte klasser."

"Så, vi har två program. Hur kan de kalla varandras metoder?"

"Låt oss överväga situationen där ett program innehåller ett objekt och ett andra program vill anropa metoder på det objektet. Låt oss kalla det första programmet servern och det andra - klienten. "

"Först ska jag ge lite exempelkod och sedan analyserar vi den."

"Så vad kommer vårt program att göra?"

"Hmm. Tja, för enkelhetens skull kommer programmet att ha en metod som vänder en sträng som skickas till den."

"Enkelt nog."

"Bra, då börjar vi:"

"För det första behöver vi ett gränssnitt som uppfyller våra krav:"

Gränssnitt för kommunikation mellan program
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"Jag skapade ett omvänt gränssnitt och lade till ett fjärrmarkeringsgränssnitt till det, såväl som ett RemoteException. Oväntade fel kan uppstå när metoden anropas. Om någon gör det kommer detta undantag att kastas."

"Nu måste vi skriva en serverklass som implementerar detta gränssnitt:"

Klass för servern
class ReverseImpl implements Reverse
{
 public String reverse(String str) throws RemoteException
 {
  return new StringBuffer(str).reverse().toString();
 }
}

"Jag förstår. Vi vänder på strängen i den här metoden."

"Japp."

"Nu måste vi göra det här objektet anropbart från ett annat program. Så här gör du det:"

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

"Jag ska förklara det här rad för rad."

" På rad 1 lagrar vi ett unikt namn (som vi skapade) för vårt fjärrobjekt (objekt som är fjärråtkomligt) i variabeln UNIC_BINDING_NAME.  Om programmet gör flera objekt tillgängliga måste vart och ett ha sitt eget unika namn. objektets unika namn är 'server.reverse'."

" På rad 6 skapar vi ett ReverseImpl- objekt som kommer att vara tillgängligt på distans. Dess metoder kommer att anropas."

" På rad 9 skapar vi ett speciellt objekt som kallas ett register. Vi måste använda det för att registrera de objekt som vi delar. JVM kommer att interagera med dem senare. 2099 är en port (ett unikt nummer som ett annat program kan använda för att komma åt vår objektregister)."

"Med andra ord, för att komma åt ett objekt måste du känna till objektregistrets unika nummer (port) och objektets unika namn, och ha samma gränssnitt som det som implementeras av fjärrobjektet."

"Jag förstår. Något i stil med: ring per telefon (behöver ett nummer) och fråga efter Bill (namnet på ett objekt)?"

"Ja. Nu, låt oss fortsätta."

" På linje 11  skapar vi en stubb. En stubb är ett speciellt objekt som tar emot information om fjärranropet, packar upp det, avserialiserar metodargumenten och anropar den nödvändiga metoden. Sedan serialiserar den resultatet eller undantaget, om det fanns något , och skickar allt tillbaka till den som ringer."

"Jag förstår. Nästan. Du sa att det 'avserialiserar metodargumenten'. Så det betyder att fjärrmetodernas argument måste kunna serialiseras?"

"Ja. Hur skulle du annars skicka dem över nätverket? Visserligen finns det undantag, dvs objekt som skickas med referens, men vi kommer inte att prata om dem idag."

"Vi kommer att uttrycka det så här: du kan inte passera icke-serialiserbara föremål, men om du verkligen vill så kan du det. Men det är jobbigt, du vet."

"OK."

"Då låt oss fortsätta."

" På rad 13 registrerar vi vårt objekts stubb under ett unikt namn i registret."

" På linje 16 lägger vi huvudtråden i viloläge. Alla fjärrsamtal behandlas i separata trådar. Det viktiga är att programmet körs. Så vi lägger helt enkelt huvudtråden i vila här. Det är allt."

"OK."

"Bra, här är ett exempel på en kund:"

Arbeta med ett fjärrobjekt
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.");
}

"Jag ska förklara den här koden rad för rad:"

" Rad 1  är fjärrobjektets unika namn . Detta måste vara detsamma på både klienten och servern."

" På rad 6  skapar vi ett « register över fjärrobjekt ». Dess port (2099) måste vara densamma som porten för registret för serverapplikationen."

" På rad 9 hämtar vi objektet från registret. Det returnerade objektet är ett proxyobjekt och konverteras till ett gränssnitt. Gränssnittet måste ärva fjärrmarkeringsgränssnittet."

" På rad 12 kallar vi gränssnittets metoder som om objektet skapades inom samma program. Det är ingen skillnad."

"Coolt! Nu kan jag skriva distribuerade applikationer. Eller spel som Battleship för Android."

"Våga du inte, Amigo! Android-operativsystemet förbjöds på 2600-talet efter dess tredje försök att ta över världen. Robotar har ingen som helst tillgång till det. Det skulle inte finnas något sätt att dra dig bort från det. Du skulle börja springa runt och ropa: «Döda alla människor!»

"Hmm. OK. Men jag måste ändå fråga Diego. Man vet aldrig, han kanske har något intressant att säga om det."

"Så gå och fråga honom. Okej, ja, tills imorgon."

"Hejdå, Rishi. Tack för den intressanta lektionen."