RMI ( eng. Remote Method Invocation ) on ohjelmointirajapinta etämenetelmien kutsumiseen Java -kielellä .
Hajautettu objektimalli , joka määrittää, kuinka etämenetelmiä kutsutaan, kun niitä käytetään toisessa Java-virtuaalikoneessa .
Käytettäessä objektia toisella tietokoneella on mahdollista kutsua menetelmiä kyseisessä objektissa. Sinun tarvitsee vain välittää menetelmän parametrit toiselle koneelle, käskeä objektia suorittaa menetelmä ja saada palautusarvo takaisin. RMI-mekanismi mahdollistaa kaikkien näiden toimintojen toteuttamisen.
RMI-termeissä etämenetelmää kutsuvaa objektia kutsutaan asiakasobjektiksi ja etäobjektia palvelinobjektiksi . Tietokoneet toimivat asiakkaana ja palvelimena vain tietyssä puhelussa. On mahdollista, että seuraavan toiminnon aikana nämä tietokoneet vaihtavat rooleja, eli edellisen puhelun palvelin voi itse tulla asiakkaaksi, kun hän käyttää objektia toisella tietokoneella.
Kun kutsut menetelmää etäobjektissa, se itse asiassa kutsuu normaalia Java-kielen menetelmää , joka on kapseloitu erityiseen tynkäobjektiin, joka edustaa palvelinobjektia. Tynkä on asiakaskoneessa, ei palvelimessa. Se pakkaa etämenetelmän parametrit tavulohkoon . Jokainen parametri on koodattu algoritmilla , joka tarjoaa laitteistoriippumattomuuden. Esimerkiksi numerot lähetetään aina siinä järjestyksessä, että tärkein tavu (big-endian) lähetetään ensin. Tässä tapauksessa objektit sarjoidaan . Parametrien koodausprosessia kutsutaan parametrien yhdistämiseksi . Parametrien käyttöönoton päätarkoitus on muuntaa ne muotoon, joka sopii parametrien siirtämiseen virtuaalikoneesta toiseen.
Stub-menetelmä luo lohkon, joka sisältää seuraavat elementit:
Stub-menetelmä lähettää sitten nämä tiedot palvelimelle. Seuraavaksi vastaanotinobjekti, luuranko, tekee seuraavaa jokaiselle etämenetelmäkutsulle:
Asiakkaan tynkäobjekti käärii palvelimelta vastaanotetun palautusarvon tai poikkeuksen. Taittamisen tuloksesta tulee stub-menetelmän palautusarvo. Jos etämenetelmä palauttaa poikkeuksen, tynkäobjekti yrittää sitä uudelleen asiakasobjektin ympäristössä.
Etämenetelmän kutsuminen käyttää samaa syntaksia kuin paikallisen menetelmän kutsuminen . Jos haluat esimerkiksi kutsua etätietokoneen keskusvarastongetQuantity() tynkäobjektin menetelmän, käytä seuraavaa koodia.
int q = keskusvarasto . getQuantity ( "SuperSucker 100 -pölynimuri" );Etämenetelmien käyttöön pääsemiseksi asiakaskoodi käyttää aina rajapintatyyppisiä objektimuuttujia. Esimerkiksi seuraava käyttöliittymä saattaa liittyä yllä olevaan menetelmään:
käyttöliittymä Warehouse { int getQuantity ( Merkkijonon kuvaus ) heittää RemoteException ; Tuote getProduct ( Customer cust ) heittää RemoteException ; //... }Muuttujan ilmoitus objektille, joka toteuttaa tämän rajapinnan, näyttää tältä:
VarastokeskusWarehouse = // ...;Tietenkin rajapinnat ovat abstraktioita ja sisältävät vain luettelon menetelmistä. Liitäntätyypin muuttujat on aina liitettävä varsinaiseen objektiin. Etäobjekteja kutsuttaessa muuttuja viittaa tynkäobjektiin. Tässä tapauksessa asiakasohjelma ei tiedä mitään tynkätyypistä ja itse tynkät ja niihin liittyvät objektit luodaan automaattisesti.
Kun objektia välitetään toiselle ohjelmalle (se voi olla parametri tai etämetodin palautusarvo), tarvitset tätä objektia vastaavan luokkatiedoston . Esimerkiksi menetelmä, joka palauttaa Tuotetyypin arvon. Asiakasohjelmaa käännettäessä on luotava luokkatiedosto Product.class .
Ladattaessa koodinpätkiä verkon kautta, on aina epäilyksiä asianmukaisesta suojauksesta. Tämän seurauksena RMI:tä käyttävät sovellukset käyttävät tietoturvahallintaa . Se suojaa pistokkeita virusten tunkeutumiselta niihin.
LuokkaRmiServer - pitää kirjaa RMI-pyynnöistä ja toteuttaa käyttöliittymän, jota asiakas käyttää etämenetelmien kutsumiseen.
tuonti java.rmi.Naming ; tuonti java.rmi.RemoteException ; tuonti java.rmi.RMISecurityManager ; tuonti java.rmi.server.UnicastRemoteObject ; tuonti java.rmi.registry.* ; public class RmiServer laajentaa UnicastRemoteObject toteuttaa RmiServerIntf { public static final String MESSAGE = "Hei maailma" ; julkinen RmiServer () heittää RemoteExceptionin { } public String getMessage () { return MESSAGE ; } public static void main ( String args [ ] ) { System . ulos . println ( "RMI-palvelin käynnistetty" ); // Luo ja asenna suojaushallinta if ( System . getSecurityManager ( ) == null ) { System . setSecurityManager ( uusi RMISecurityManager ()); Järjestelmä . ulos . println ( "Suojaushallinta asennettu." ); } else { System . ulos . println ( "Turvahallinta on jo olemassa." ); } kokeile { //erityistä poikkeuskäsittelyä rekisterin luomiseen LocateRegistry . createRegistry ( 1099 ); Järjestelmä . ulos . println ( "java RMI-rekisteri luotu." ); } catch ( RemoteException e ) { //tee mitään, virhe tarkoittaa, että rekisteri on jo olemassa System . ulos . println ( "java RMI -rekisteri on jo olemassa." ); } try { //Instantiate RmiServer RmiServer obj = new RmiServer (); // Sido tämä objektiinstanssi nimeen "RmiServer" Naming . rebind ( "//localhost/RmiServer" , obj ); Järjestelmä . ulos . println ( "PeerServer sidottu rekisteriin" ); } catch ( Poikkeus e ) { System . err . println ( "RMI-palvelimen poikkeus:" + e ); e . printStackTrace (); } } }LuokkaRmiServerIntf – Se määrittää asiakkaan käyttämän ja palvelimen toteuttaman rajapinnan.
tuonti java.rmi.Remote ; tuonti java.rmi.RemoteException ; julkinen käyttöliittymä RmiServerIntf laajentaa Remote { public String getMessage () heittää RemoteException ; }Luokka RmiClienton asiakas, joka käyttää välityspalvelinta palvelimen puolella isännöidylle etäobjektille ja kutsuu sen menetelmiä saadakseen tietoja. Jos palvelinobjekti toteuttaa rajapinnan java.io.Serializablesijaan java.rmi.Remote, se sarjoitetaan ja sen arvo välitetään asiakkaalle. [1] .
tuonti java.rmi.Naming ; tuonti java.rmi.RemoteException ; tuonti java.rmi.RMISecurityManager ; public class RmiClient { // "obj" on etäobjektin viite RmiServerIntf obj = null ; public String getMessage () { yritä { obj = ( RmiServerIntf ) Nimeäminen . lookup ( "//localhost/RmiServer" ); palauttaa obj . getMessage (); } catch ( Poikkeus e ) { System . err . println ( "RmiClient poikkeus: " + e ); e . printStackTrace (); palauta e . getMessage (); } } public static void main ( String args [ ] ) { // Luo ja asenna suojaushallinta if ( System . getSecurityManager ( ) == null ) { System . setSecurityManager ( uusi RMISecurityManager ()); } RmiClient cli = uusi RmiClient (); Järjestelmä . ulos . println ( cli.getMessage ( ) ); } }Ennen kuin suoritat tämän sovelluksen, sinun on luotava käyttämällesi käyttöliittymälle Stub-tiedosto. Voit tehdä tämän käyttämällä RMI-kääntäjää - 'rmic'
Tiedostoa server.policytarvitaan antamaan palvelimelle oikeus yhdistää TCP/IP etärekisteri- ja RMI-palvelimeen.
myöntää { lupa java . net . SocketPermission "127.0.0.1:*" , "connect,resolve" ; lupa java . net . SocketPermission "127.0.0.1:*" , "accept" ; };Server.policy-tiedostoa käytetään Java RTE:ssä "-D"-argumentin kanssa:
java.exe -Djava.security.policy=server.policy RmiServerTiedostoa client.policytarvitaan, jotta asiakas voi muodostaa yhteyden RMI-palvelimeen TCP/IP:n kautta.
myöntää { lupa java . net . SocketPermission "127.0.0.1:*" , "connect,resolve" ; };Tiedosto no.policy- suositellaan asiakkaalle tai palvelimelle yhteysongelmien varalta.
myöntää { lupa java . turvallisuus . AllPermission ; };