JavaRush /Java Blog /Random-TK /RMI: ulanmak tejribesi

RMI: ulanmak tejribesi

Toparda çap edildi
Salam! Bu gün has gyzykly mowzuga - RMI serederis . Bu uzakdaky usul çakylygyny aňladýar . RMI: ulanmak tejribesi - 1RMI bilen, dürli kompýuterlerde bolsa-da, biri-biri bilen aragatnaşyk saklamagy iki programma öwredip bilersiňiz. Gowy sesler? :) Emma muny etmek beýle kyn däl! Şu günki leksiýamyzda RMI täsiriniň haýsy böleklerden ybaratdygyny we ony nädip sazlamalydygyna düşüneris. Ilki bilen bize müşderi we serwer gerek . Kompýuter terminologiýasyna gaty çuňňur girmek hökman däl. RMI meselesinde bu diňe iki programma. Olaryň birinde haýsydyr bir obýekt bolar, ikinjisi bu obýektiň usullaryny çagyrar. Başga bir programmada ýerleşýän bir programmada obýektiň jaň usullary - muny öň hiç haçan etmändik! Synap görmegiň wagty geldi! :) wildabany tebigata gark bolmazlyk üçin programmamyz ýönekeý bolsun. Umuman alanyňda, serwerler adatça müşderiniň isleýän haýsydyr bir hasaplamalaryny amala aşyrýarlar. Bu hem biziň üçin bolar. Serwer hökmünde ýönekeý kalkulýator programmamyz bolar. Onuň diňe bir usuly bolar - multiply(). Müşderi programmasy tarapyndan iberilen iki belgini köpelder we netijäni gaýtaryp berer. Ilki bilen interfeýs gerek:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Näme üçin interfeýs gerek? Hakykat, RMI-iň işi öňki leksiýalaryň birinde öwrenen proksi döretmäge esaslanýar . Proksi bilen işlemek, ýadyňyzda bolsa, sapaklar däl-de, interfeýs derejesinde takyk ýerine ýetirilýär. Interfeýsimiz üçin 2 möhüm talap bar!
  1. Uzakdan token interfeýsini miras almaly.
  2. Itshli usullary RemoteException-y zyňmalydyr (bu IDE-de awtomatiki usulda ýerine ýetirilmeýär, el bilen ýazmaly!).
Indi interfeýsimizi durmuşa geçirjek serwer synpyny döretmeli Calculator. RMI: ulanmak tejribesi - 2Bu ýerdäki hemme zat gaty ýönekeý:
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

   @Override
   public int multiply(int x, int y) throws RemoteException {
       return x*y;
   }

}
Bu ýerde teswir ýazmak üçin kän zat ýok :) Indi serwerimiziň kalkulýator synpyny düzjek we işletjek serwer programmasyny ýazmaly. Bu şeýle bolar:
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class ServerMain {

   public static final String UNIQUE_BINDING_NAME = "server.calculator";

   public static void main(String[] args) throws RemoteException, AlreadyBoundException, InterruptedException {

       final RemoteCalculationServer server = new RemoteCalculationServer();

       final Registry registry = LocateRegistry.createRegistry(2732);

       Remote stub = UnicastRemoteObject.exportObject(server, 0);
       registry.bind(UNIQUE_BINDING_NAME, stub);

       Thread.sleep(Integer.MAX_VALUE);

   }
}
Geliň, muny kesgitläliň :) Birinji setirde haýsydyr bir setir üýtgeýjisini döredýäris:
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Bu setir uzakdaky obýektiň özboluşly adydyr . Bu at bilen müşderi programmasy serwerimizi tapyp biler: muny soň görersiňiz. Ondan soň kalkulýator obýektimizi döredýäris:
final RemoteCalculationServer server = new RemoteCalculationServer();
Bu ýerde hemme zat düşnüklidir. Aşakdakylar has gyzykly:
final Registry registry = LocateRegistry.createRegistry(2732);
Hasaba alyş diýilýän zat, öçürilen zatlaryň sanawy . "Öçürildi" olary kompýuterden pozanymyz manysynda däl-de, bu sanawdaky obýektlere beýleki programmalardan uzakdan girip bolýandygy sebäpli :) LocateRegistry.createRegistry()2732 belgisini usula geçirdik. Bu port belgisi. Portuň nämedigini bilmeseňiz, şu ýerde okap bilersiňiz , ýöne häzirlikçe bu programmanyň beýleki programmalaryň obýekt sanawymyzy tapyp bilýän özboluşly bir belgidigini ýadyňyzdan çykarmaly dälsiňiz (aşakda hem görersiňiz). Geliň dowam edeliň. Indiki setirde nämeleriň bolýandygyny göreliň:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Bu setirde stub döredýäris . Bir stub uzakdaky jaň prosesini öz içine alýar. Munuň RMI-iň iň möhüm elementidigini aýdyp bolar . Ol näme edýär?
  1. Usula uzakdan jaň etmek baradaky ähli maglumatlary alýar.
  2. Usulyň parametrleri bar bolsa, stub olary deserializasiýa edýär. Bu meselä üns beriň! Uzakdan jaň etmegiň usullaryna geçýän parametrleriňiz yzygiderli bolmaly (ahyrsoňy, olar tor arkaly geçiriler). Bizde beýle problema ýok - diňe sanlary iberýäris. Objectsöne obýektleri geçirýän bolsaňyz, ýatdan çykarmaň!
  3. Ondan soň islenýän usul diýilýär.
UnicastRemoteObject.exportObject()Serwer kalkulýator obýektimizi usula geçirýäris . Şeýlelik bilen, usullaryny uzakdan çagyrmaga mümkinçilik berýäris. Bizde diňe bir zat galmaly:
registry.bind(UNIQUE_BINDING_NAME, stub);
Stubymyzy ilkibaşda döreden adymyz bilen uzakdaky obýektleriň sanawyna ýazýarys. Indi müşderi tapyp biler! Ahyrynda programmanyň esasy sapagyny uklaýandygymyzy gören bolmagyňyz mümkin:
Thread.sleep(Integer.MAX_VALUE);
Diňe serweri uzak wagtlap saklamaly. IDEa-da birbada iki usuly işlederis main(): ilki serwer biri ( ServerMaineýýäm ýazan synpymyzda), soň bolsa müşderi usuly (aşakda ClientMainýazarys). Müşderini işe girizýän wagtymyz serwer programmasynyň peselmezligi möhümdir, şonuň üçin ony uzak wagtlap uklaýarys. Entegem işlär :) Indi main()serwer usulymyzy işledip bileris. Goý, işlediň we müşderi programmasynyň haýsydyr bir usul çagyrmagyna garaşyň :) Indi müşderi programmasy ýazalyň! Köpeltmek üçin serwerimize san iberer.
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class ClientMain {

   public static final String UNIQUE_BINDING_NAME = "server.calculator";

   public static void main(String[] args) throws RemoteException, NotBoundException {

       final Registry registry = LocateRegistry.getRegistry(2732);

       Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);

       int multiplyResult = calculator.multiply(20, 30);

       System.out.println(multiplyResult);
   }
}
Ol çylşyrymly görünýär. Bu ýerde näme bolýar? Ilki bilen, müşderi uzakdan jaň etjek obýektiň özboluşly adyndan habarly bolmalydyr. Şonuň üçin müşderi programmasynda üýtgeýjini hem döretdik. public static final String UNIQUE_BINDING_NAME = "server.calculator"; Indiki usulda main()uzakdaky obýektleriň sanawyna girip bileris. Munuň üçin usuly çagyrmaly LocateRegistry.getRegistry()we ServerMain programmasynda - 2732 portda bellige alnan port belgimizi şol ýerden geçirmeli (bu san mysal üçin saýlandy, başga birini ulanyp görüp bilersiňiz):
final Registry registry = LocateRegistry.getRegistry(2732);
Indi etmeli zadymyz, sanawdan islenýän zady almak! Bu aňsat, sebäbi biz onuň adyny bilýäris!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Kasting görnüşine üns beriň. Alnan obýekti anyk synp däl-de, interfeýsdeCalculator goýýarys RemoteCalculationServer. Leksiýanyň başynda aýdyşymyz ýaly, RMI proksi ulanmaga esaslanýar, şonuň üçin uzakdan jaň diňe sapaklar däl-de, interfeýs usullary üçin elýeterlidir. Netijede, multiply()obýektimizdäki bir usuly uzakdan çagyrýarys we netijäni konsola çap edýäris.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Usuly main()synpda köp wagt öň başladyk, usuly müşderi programmasynda ServerMainişe girizmegiň wagty geldi ! Konsol çykyşy: 600 Ine! Maksatnamamyz (hatda ikisi hem!) Işini üstünlikli ýerine ýetirdi :) Wagtyňyz we islegiňiz bar bolsa, ony birneme diwersifikasiýa edip bilersiňiz. Mysal üçin, kalkulýatoryň san däl-de, bir obýektiň parametr hökmünde geçendigine göz ýetiriň . Goşmaça material hökmünde makalalara we mysallara seredip bilersiňiz - şu ýerde: main()ClientMainCalculationInstance(int x, int y) Indiki sapaklarda görüşeris! :)
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION