"Hallo! En nog een leuk onderwerp: RMI. RMI staat voor Remote Method Invocation . Met andere woorden, RMI is een mechanisme waarmee een object van de ene Java-machine methoden kan aanroepen op objecten van een andere Java-machine , zelfs als ze zich op verschillende computers, in verschillende landen of aan verschillende kanten van de wereld."

KMI - 1

"Ho! Dat klinkt geweldig."

"Ja. Maar ik zal alleen proberen je een overzicht te geven. Als je hiermee te diep graaft, kun je in de war raken door de nuances van hoe het werkt."

"Maar als je niet tot het uiterste gaat, dan is RMI niet alleen heel eenvoudig, maar vereenvoudigt het ook het leven van een programmeur aanzienlijk. Daarvoor betuigen we onze diepste respect."

"Dus we willen dat één object in een Java-programma een methode aanroept op een object dat zich in een ander Java-programma bevindt. Ongeacht waar deze programma's worden uitgevoerd."

"Laten we het eenvoudigste voorbeeld bekijken: wanneer beide programma's op dezelfde computer draaien.  Om programma's via internet te laten communiceren, moet u de machtigingen van de JVM configureren , maar daar gaan we vandaag niet op in."

"In Java kun je op afstand alleen de methoden van interfaces aanroepen, geen klassen."

"Dus we hebben twee programma's. Hoe kunnen ze elkaars methoden aanroepen?"

"Laten we eens kijken naar de situatie waarin het ene programma een object bevat en een tweede programma methodes op dat object wil aanroepen. Laten we het eerste programma de server noemen en het tweede de client. "

"Eerst geef ik wat voorbeeldcode en dan gaan we die analyseren."

"Dus wat zal ons programma doen?"

"Hmm. Nou, voor de eenvoud heeft het programma één methode die een string omkeert die eraan wordt doorgegeven."

"Simpel genoeg."

"Goed, dan gaan we beginnen:"

"Ten eerste hebben we een interface nodig die aan onze eisen voldoet:"

Interface voor communicatie tussen programma's
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"Ik heb een Reverse-interface gemaakt en er een Remote Marker-interface aan toegevoegd, evenals een RemoteException. Onverwachte fouten kunnen optreden wanneer de methode wordt aangeroepen. Als dat het geval is, wordt deze uitzondering gegenereerd."

"Nu moeten we een serverklasse schrijven die deze interface implementeert:"

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

"Ik begrijp het. We keren de string in deze methode om."

"Ja."

"Nu moeten we dit object oproepbaar maken vanuit een ander programma. Zo doe je dat:"

Objecten delen
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);
}

"Ik zal dit regel voor regel uitleggen."

" In regel 1 slaan we een unieke naam (die we hebben verzonnen) op voor ons object op afstand (object dat op afstand toegankelijk is) in de variabele  UNIC_BINDING_NAME . Als het programma meerdere objecten toegankelijk maakt, moet elk zijn eigen unieke naam hebben. de unieke naam van het object is 'server.reverse'."

" Op regel 6 maken we een ReverseImpl- object dat op afstand toegankelijk is. De methoden worden aangeroepen."

" Op regel 9 maken we een speciaal object, een register genaamd. We moeten het gebruiken om de objecten die we delen te registreren. De JVM zal er later mee communiceren. 2099 is een poort (een uniek nummer dat een ander programma kan gebruiken om toegang te krijgen tot onze objectregister)."

"Met andere woorden, om toegang te krijgen tot een object, moet u het unieke nummer (poort) van het objectregister en de unieke naam van het object kennen, en dezelfde interface hebben als die geïmplementeerd door het externe object."

"Ik snap het. Iets als: bellen via de telefoon (nummer nodig) en vragen naar Bill (de naam van een object)?"

"Ja. Laten we nu verder gaan."

" Op regel 11  maken we een stub. Een stub is een speciaal object dat informatie ontvangt over de oproep op afstand, deze uitpakt, de methodeargumenten deserialiseert en de vereiste methode aanroept. Vervolgens serialiseert het het resultaat of de uitzondering, als die er was en stuurt het allemaal terug naar de beller."

'Ik snap het. Bijna. Je zei dat het 'de methode-argumenten deserialiseert'. Dat betekent dus dat de argumenten van de methoden op afstand geserialiseerd moeten kunnen worden?'

"Ja. Hoe zou je ze anders over het netwerk kunnen sturen? Toegegeven, er zijn uitzonderingen, dat wil zeggen objecten die door verwijzing worden doorgegeven, maar daar zullen we het vandaag niet over hebben."

"We zullen het zo zeggen: je kunt niet-serialiseerbare objecten niet passeren, maar als je het echt wilt, dan kan het. Maar het is lastig, weet je."

"OK."

"Laten we dan maar doorgaan."

" Op regel 13 registreren we de stub van ons object onder een unieke naam in het register."

" Op lijn 16 zetten we de hoofdthread in de slaapstand. Alle externe oproepen worden verwerkt op aparte threads. Het belangrijkste is dat het programma draait. Dus we zetten de hoofdthread hier gewoon in de slaapstand. Dat is alles."

"OK."

"Mooi, dan is hier een voorbeeld van een klant:"

Werken met een object op afstand
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.");
}

"Ik zal deze code regel voor regel uitleggen:"

" Regel 1 is de unieke naam  van het externe object . Deze moet hetzelfde zijn op zowel de client als de server."

" In regel 6  maken we een « register van objecten op afstand » aan. De poort (2099) moet dezelfde zijn als de poort van het register voor de servertoepassing."

" Op regel 9 halen we het object uit het register. Het geretourneerde object is een proxyobject en wordt geconverteerd naar een interface. De interface moet de Remote Marker-interface erven."

" Op regel 12 noemen we de methoden van de interface alsof het object binnen hetzelfde programma is gemaakt. Er is geen verschil."

"Cool! Nu kan ik gedistribueerde applicaties schrijven. Of games zoals Battleship voor Android."

"Waag het niet, Amigo! Het Android-besturingssysteem werd in de 27e eeuw verboden na de derde poging om de wereld over te nemen. Robots hebben er geen enkele toegang toe. Er is geen enkele manier om je eraan te onttrekken Je begon rond te rennen terwijl je riep: «Dood alle mensen!»'

"Hmm. Oké. Maar ik zal het Diego toch moeten vragen. Je weet maar nooit, misschien heeft hij er iets interessants over te zeggen."

'Ga het hem dan maar vragen. Oké, nou, tot morgen.'

"Dag, Rishi. Bedankt voor de interessante les."