Aan de slag met Java RMI

1. Overzicht

Wanneer twee JVM's moeten communiceren, is Java RMI een optie die we moeten laten gebeuren. In dit artikel zullen we een eenvoudig voorbeeld opstarten waarin de Java RMI-technologie wordt getoond.

2. Creëren van de server

Er zijn twee stappen nodig om een ​​RMI-server te maken:

  1. Maak een interface die het client / server-contract definieert.
  2. Maak een implementatie van die interface.

2.1. Het contract bepalen

Laten we eerst de interface voor het externe object maken. Deze interface breidt het java.rmi.Remote marker interface.

Bovendien gooit elke methode die in de interface wordt gedeclareerd de java.rmi.RemoteException:

openbare interface MessengerService breidt Remote {String sendMessage (String clientMessage) uit met RemoteException; }

Merk echter op dat RMI de volledige Java-specificatie voor methodehandtekeningen ondersteunt, zolang de Java-typen worden geïmplementeerd java.io.Serializable.

We zullen in toekomstige secties zien hoe zowel de client als de server deze interface zullen gebruiken.

Voor de server maken we de implementatie, ook wel het Afgelegen object.

Voor de klant, de RMI-bibliotheek maakt dynamisch een implementatie met de naam een Stomp.

2.2. Implementatie

Laten we verder de externe interface implementeren, opnieuw de Afgelegen object:

public class MessengerServiceImpl implementeert MessengerService {@Override public String sendMessage (String clientMessage) {return "Client Message" .equals (clientMessage)? "Serverbericht": null; } public String unposedMethod () {/ * code * /}}

Merk op dat we de gooitRemoteException clausule uit de methodedefinitie.

Het zou ongebruikelijk zijn dat ons verre object een RemoteException aangezien deze uitzondering doorgaans is gereserveerd voor de RMI-bibliotheek om communicatiefouten naar de client te brengen.

Het weglaten ervan heeft ook het voordeel dat onze implementatie RMI-agnostisch blijft.

Ook, alle aanvullende methoden die in het externe object zijn gedefinieerd, maar niet in de interface, blijven onzichtbaar voor de klant.

3. De service registreren

Zodra we de implementatie op afstand hebben gemaakt, moeten we het externe object binden aan een RMI-register.

3.1. Een stub maken

Eerst moeten we een stomp maken van ons externe object:

MessengerService-server = nieuwe MessengerServiceImpl (); MessengerService stub = (MessengerService) UnicastRemoteObject .exportObject ((MessengerService) server, 0);

We gebruiken de statische UnicastRemoteObject.exportObject methode om onze stub-implementatie te maken. De stub is wat de magie doet van communicatie met de server via het onderliggende RMI-protocol.

Het eerste argument om exportObject is het externe serverobject.

Het tweede argument is de poort die exportObject gebruikt voor het exporteren van het externe object naar het register.

Het geven van een waarde van nul geeft aan dat het ons niet kan schelen welke poort exportObject gebruik, dat typisch is en dus dynamisch gekozen.

Helaas, de exportObject () methode zonder poortnummer is verouderd.

3.2 Een register aanmaken

We kunnen een registerlokaal voor onze server plaatsen of als een afzonderlijke zelfstandige service.

Voor de eenvoud maken we er een die lokaal is voor onze server:

Registerregister = LocateRegistry.createRegistry (1099);

Dit creëert een register waaraan stubs kunnen worden gebonden door servers en ontdekt door clients.

We hebben ook de createRegistry methode, aangezien we het register lokaal voor de server maken.

Standaard draait een RMI-register op poort 1099. In plaats daarvan kan ook een andere poort worden opgegeven in het createRegistry fabrieks methode.

Maar in het zelfstandige geval zouden we bellen getRegistry, door de hostnaam en het poortnummer door te geven als parameters.

3.3 Het binden van de stomp

Laten we daarom onze stub aan het register binden. Een RMI-register is een naamgevingsfaciliteit zoals JNDI enz. We kunnen hier een soortgelijk patroon volgen door onze stub aan een unieke sleutel te binden:

registry.rebind ("MessengerService", stub); 

Het resultaat is dat het externe object nu beschikbaar is voor elke client die het register kan vinden.

4. Creëren van de klant

Laten we tot slot de client schrijven om de externe methoden aan te roepen.

Om dit te doen, zoeken we eerst het RMI-register. Bovendien zoeken we de externe objectstub op met behulp van de begrensde unieke sleutel.

En tot slot doen we beroep op de bericht versturen methode:

Registerregister = LocateRegistry.getRegistry (); MessengerService server = (MessengerService) register .lookup ("MessengerService"); String responseMessage = server.sendMessage ("Clientbericht"); String verwachteMessage = "Serverbericht"; assertEquals (verwachteMessage, responseMessage);

Omdat we het RMI-register op de lokale computer en standaardpoort 1099 uitvoeren, geven we geen parameters door aan getRegistry.

Inderdaad, als het register zich liever op een andere host of een andere poort bevindt, kunnen we deze parameters opgeven.

Zodra we het stub-object opzoeken met behulp van het register, kunnen we de methoden op de externe server aanroepen.

5. Conclusie

In deze tutorial kregen we een korte inleiding tot Java RMI en hoe dit de basis kan zijn voor client-servertoepassingen. Blijf op de hoogte voor extra berichten over enkele van de unieke functies van RMI!

De broncode van deze tutorial is te vinden op GitHub.