JavaRush /Java Blog /Random-TL /RMI: kasanayan sa paggamit

RMI: kasanayan sa paggamit

Nai-publish sa grupo
Kamusta! Ngayon ay titingnan natin ang isang medyo kawili-wiling paksa - RMI . Ito ay kumakatawan sa Remote Method Invocation . RMI: kasanayan sa paggamit - 1Sa RMI, maaari kang magturo ng dalawang programa upang makipag-usap sa isa't isa, kahit na sila ay nasa magkaibang mga computer. Mukhang cool? :) Ngunit hindi ito napakahirap gawin! Sa lecture ngayon, mauunawaan natin kung anong mga bahagi ang binubuo ng RMI interaction at kung paano ito i-configure. Ang unang bagay na kailangan namin ay isang kliyente at isang server . Hindi mo kailangang masyadong malalim sa terminolohiya ng computer. Sa kaso ng RMI, ito ay dalawang programa lamang. Ang isa sa kanila ay maglalaman ng ilang bagay, at ang pangalawa ay tatawag ng mga pamamaraan ng bagay na ito. Mga pamamaraan ng pagtawag ng isang bagay sa isang programa na matatagpuan sa isa pang programa - hindi pa namin ito nagawa dati! Oras na para subukan ito! :) Upang hindi malunod sa kagubatan, maging simple ang ating programa. Sa pangkalahatan, ang mga server ay karaniwang nagsasagawa ng ilang uri ng mga kalkulasyon na hinihiling ng kliyente. Ito ay magiging pareho para sa amin. Magkakaroon kami ng isang simpleng calculator program bilang isang server. Magkakaroon lamang siya ng isang paraan - multiply(). Paparamihin nito ang dalawang numero na ipinadala dito ng programa ng kliyente at ibabalik ang resulta. Una sa lahat kailangan namin ng isang interface:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Bakit kailangan natin ng interface? Ang katotohanan ay ang gawain ng RMI ay batay sa paglikha ng mga proxy, na iyong pinag-aralan sa isa sa mga nakaraang lektura . At magtrabaho kasama ang mga proxy, tulad ng malamang na naaalala mo, ay isinasagawa nang tumpak sa antas ng mga interface, hindi mga klase. Mayroong 2 mahalagang kinakailangan para sa aming interface!
  1. Dapat itong magmana ng Remote na interface ng token.
  2. Ang lahat ng mga pamamaraan nito ay dapat magtapon ng isang RemoteException (ito ay hindi awtomatikong ginagawa sa IDE, kailangan mong isulat ito nang manu-mano!).
Ngayon kailangan naming lumikha ng isang klase ng server na magpapatupad ng aming interface Calculator. RMI: kasanayan sa paggamit - 2Ang lahat dito ay medyo simple din:
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

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

}
Wala na masyadong maikomento dito :) Ngayon ay kailangan nating magsulat ng isang server program na magko-configure at maglulunsad ng aming server calculator class. Magiging ganito ang hitsura:
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);

   }
}
Alamin natin ito :) Sa unang linya lumikha tayo ng ilang uri ng string variable:
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Ang string na ito ay ang natatanging pangalan ng remote na bagay . Sa pamamagitan ng pangalang ito, mahahanap ng programa ng kliyente ang aming server: makikita mo ito sa ibang pagkakataon. Susunod na nilikha namin ang aming calculator object:
final RemoteCalculationServer server = new RemoteCalculationServer();
Malinaw ang lahat dito. Ang mga sumusunod ay mas kawili-wili:
final Registry registry = LocateRegistry.createRegistry(2732);
Ang bagay na ito na tinatawag na Registry ay isang registry ng mga tinanggal na bagay . "Natanggal" hindi sa kahulugan na tinanggal namin ang mga ito mula sa computer, ngunit sa katotohanan na ang mga bagay mula sa rehistrong ito ay maaaring ma-access nang malayuan mula sa iba pang mga programa :) LocateRegistry.createRegistry()Ipinasa namin ang numerong 2732 sa pamamaraan. Ito ang numero ng port. Kung hindi mo alam kung ano ang port, maaari mo itong basahin dito , ngunit sa ngayon kailangan mo lang tandaan na ito ay isang natatanging numero kung saan mahahanap ng iba pang mga programa ang aming object registry (makikita mo rin ito sa ibaba). Mag-move on na tayo. Tingnan natin kung ano ang mangyayari sa susunod na linya:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Sa linyang ito lumikha kami ng isang usbong . Sinasaklaw ng isang stub ang buong proseso ng remote na tawag sa loob mismo nito. Masasabing ito ang pinakamahalagang elemento ng RMI. Ano ang ginagawa niya?
  1. Natatanggap ang lahat ng impormasyon tungkol sa isang malayuang tawag sa isang paraan.
  2. Kung ang pamamaraan ay may mga parameter, ang stub ay nagde-deserialize sa kanila. Bigyang-pansin ang puntong ito! Ang mga parameter na ipapasa mo sa mga pamamaraan para sa mga malalayong tawag ay dapat na serializable (pagkatapos ng lahat, ipapadala ang mga ito sa network). Wala kaming ganoong problema - nagpapadala lang kami ng mga numero. Ngunit kung ililipat mo ang mga bagay, huwag kalimutan ang tungkol dito!
  3. Pagkatapos nito, tinawag nito ang nais na pamamaraan.
Ipinapasa namin UnicastRemoteObject.exportObject()ang object ng aming calculator ng server sa pamamaraan. Sa ganitong paraan ginagawa naming posible na tawagan ang mga pamamaraan nito nang malayuan. Isa na lang ang kailangan nating gawin:
registry.bind(UNIQUE_BINDING_NAME, stub);
"Inirerehistro" namin ang aming stub sa remote object registry sa ilalim ng pangalang naisip namin sa pinakadulo simula. Ngayon ay mahahanap na ito ng kliyente! Maaaring napansin mo na sa dulo inilalagay namin ang pangunahing thread ng programa sa pagtulog:
Thread.sleep(Integer.MAX_VALUE);
Kailangan lang nating panatilihing tumatakbo ang server nang mahabang panahon. Magpapatakbo kami ng dalawang pamamaraan sa IDEa nang sabay-sabay main(): una ang server (sa klase ServerMainna naisulat na namin), at pagkatapos ay ang kliyente (sa klase ClientMainay isusulat namin sa ibaba). Mahalagang hindi bumaba ang programa ng server habang inilulunsad namin ang kliyente, kaya pinatulog lang namin ito ng mahabang panahon. Ito ay gagana pa rin :) Ngayon ay maaari na naming patakbuhin main()ang aming paraan ng server. Hayaan itong tumakbo at hintayin ang client program na tumawag ng ilang paraan :) Ngayon ay magsulat tayo ng isang client program! Magpapadala ito ng mga numero sa aming server para dumami.
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);
   }
}
Mukha siyang hindi komplikado. Anong nangyayari dito? Una, dapat malaman ng kliyente ang natatanging pangalan ng bagay na ang mga pamamaraan ay tatawagin nito nang malayuan. Samakatuwid, sa programa ng kliyente lumikha din kami ng isang variable.Susunod public static final String UNIQUE_BINDING_NAME = "server.calculator"; , sa pamamaraan main()na nakakakuha kami ng access sa rehistro ng mga malalayong bagay. Upang gawin ito, kailangan naming tawagan ang pamamaraan LocateRegistry.getRegistry()at ipasa doon ang numero ng port kung saan nilikha ang aming rehistro sa programa ng ServerMain - port 2732 (ang numerong ito ay pinili bilang isang halimbawa, maaari mong subukang gumamit ng isa pa):
final Registry registry = LocateRegistry.getRegistry(2732);
Ngayon ang kailangan lang nating gawin ay makuha ang ninanais na bagay mula sa rehistro! Madali lang dahil alam natin ang kanyang natatanging pangalan!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Bigyang-pansin ang uri ng paghahagis. Inihagis namin ang nagresultang bagay sa isang interface Calculatorsa halip na isang kongkretong klase RemoteCalculationServer . Tulad ng sinabi namin sa simula ng panayam, ang RMI ay batay sa paggamit ng isang proxy, kaya ang isang remote na tawag ay magagamit lamang para sa mga pamamaraan ng mga interface, hindi mga klase. Sa dulo, malayo kaming tumawag ng isang paraan multiply()sa aming bagay at i-print ang resulta sa console.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Inilunsad namin ang pamamaraan main()sa klase ServerMainmatagal na ang nakalipas, oras na upang ilunsad ang pamamaraan main()sa programa ng kliyente ClientMain! Output ng console: 600 Iyon na! Ang aming programa (kahit dalawa!) ay matagumpay na natupad ang pag-andar nito :) Kung mayroon kang oras at pagnanais, maaari mong pag-iba-ibahin ito nang kaunti. Halimbawa, tiyaking sinusuportahan ng calculator ang lahat ng apat na karaniwang operasyon, at hindi ang mga numero, ngunit ang isang bagay ay ipinapasa bilang mga parameter CalculationInstance(int x, int y). Bilang karagdagang materyal, maaari kang tumingin sa mga artikulo at halimbawa - dito: Magkita-kita tayo sa mga susunod na klase! :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION