JavaRush /Блоги Java /Random-TG /RMI: амалияи истифода

RMI: амалияи истифода

Дар гурӯҳ нашр шудааст
Салом! Имрӯз мо як мавзӯи ҷолибро дида мебароем - RMI . Ин барои даъвати усули дурдаст аст . RMI: амалияи истифода - 1Бо RMI, шумо метавонед ду барномаро бо ҳамдигар муошират кунед, ҳатто агар онҳо дар компютерҳои гуногун бошанд. Хуб садо медиҳад? :) Аммо ин кор чандон душвор нест! Дар лексияи имрӯза мо мефаҳмем, ки таъсири RMI аз кадом қисмҳо иборат аст ва чӣ тавр онро танзим кардан мумкин аст. Аввалин чизе, ки ба мо лозим аст, муштарӣ ва server аст . Ба шумо лозим нест, ки ба истилоҳоти компютерӣ хеле амиқ равед. Дар мавриди RMI, инҳо танҳо ду барнома мебошанд. Яке аз онҳо ягон an objectро дар бар мегирад ва дуюмӣ методҳои ин an objectро даъват мекунад. Занг задани усулҳои an object дар як барнома, ки дар барномаи дигар ҷойгир аст - мо ҳеҷ гоҳ ин корро накарда будем! Вақти он расидааст, ки онро санҷед! :) Барои он ки дар ваҳшӣ ғарқ нашавад, бигзор барномаи мо оддӣ бошад. Умуман, serverҳо одатан як намуди ҳисобҳоро иҷро мекунанд, ки муштарӣ дархост мекунад. Барои мо хам хамин тавр мешавад. Мо ҳамчун server як барномаи ҳисобкунаки оддӣ дорем. Вай танҳо як усул хоҳад дошт - multiply(). Он ду рақамеро, ки барномаи муштарӣ ба он фиристодааст, афзоиш медиҳад ва натиҷаро бармегардонад. Пеш аз ҳама ба мо интерфейс лозим аст:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Чаро ба мо интерфейс лозим аст? Гап дар он аст, ки кори RMI ба эҷоди проксиҳо асос ёфтааст, ки шумо дар яке аз лексияҳои қаблӣ омӯхтаед . Ва кор бо проксиҳо, тавре ки шумо эҳтимол дар ёд доред, маҳз дар сатҳи интерфейсҳо анҷом дода мешавад, на дарсҳо. Барои интерфейси мо 2 талаботи муҳим вуҷуд дорад!
  1. Он бояд интерфейси аломати дурдаст мерос гирад.
  2. Ҳамаи усулҳои он бояд RemoteException-ро партоянд (ин дар IDE ба таври худкор иҷро намешавад, шумо бояд онро дастӣ нависед!).
Ҳоло мо бояд синфи serverеро созем, ки интерфейси моро амалӣ кунад Calculator. RMI: амалияи истифода - 2Дар ин ҷо ҳама чиз хеле оддӣ аст:
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

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

}
Дар ин ҷо ҳатто шарҳи зиёде вуҷуд надорад :) Ҳоло мо бояд барномаи serverеро нависем, ки синфи ҳисобкунаки serverи моро танзим ва оғоз кунад. Ин чунин хоҳад буд:
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);

   }
}
Биёед инро фаҳмем :) Дар сатри аввал мо як навъи тағирёбандаи сатрро эҷод мекунем:
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Ин сатр номи беназири an objectи дурдаст аст . Бо ин ном барномаи муштарӣ метавонад serverи моро пайдо кунад: шумо инро дертар хоҳед дид. Минбаъд мо an objectи ҳисобкунаки худро эҷод мекунем:
final RemoteCalculationServer server = new RemoteCalculationServer();
Дар ин ҷо ҳама чиз равшан аст. Инҳо ҷолибтаранд:
final Registry registry = LocateRegistry.createRegistry(2732);
Ин чизе, ки Реестр ном дорад, феҳристи an objectҳои ҳазфшуда мебошад . "Нест карда шуд" на ба он маъно, ки мо онҳоро аз компютер нест кардаем, балки дар он аст, ки an objectҳои ин реестрро аз дигар барномаҳои фосилавӣ дастрас кардан мумкин аст :) LocateRegistry.createRegistry()Мо рақами 2732-ро ба усул гузаронидем.Ин рақами порт аст. Агар шумо намедонед, ки порт чист, шумо метавонед онро дар ин ҷо хонед , аммо ҳоло шумо танҳо бояд дар хотир доред, ки ин рақами беназирест, ки тавассути он барномаҳои дигар феҳристи an objectи моро пайдо карда метавонанд (шумо инро дар зер хоҳед дид). Биёед пеш равем. Биёед бубинем, ки дар сатри оянда чӣ мешавад:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Дар ин сатр мо ноустувор эҷод мекунем . Ноустувор тамоми раванди занги дурдастро дар дохor худ фаро мегирад. Метавон гуфт, ки ин муҳимтарин унсури RMI аст. Вай чӣ кор мекунад?
  1. Ҳама маълумотро дар бораи занги дурдаст ба усул қабул мекунад.
  2. Агар усул параметрҳо дошта бошад, ноустувор онҳоро ғайрисериявӣ мекунад. Ба ин нукта диққат диҳед! Параметрҳое, ки шумо ба усулҳои зангҳои дурдаст мегузаред, бояд сериализатсияшаванда бошанд (дар ниҳоят, онҳо тавассути шабака интиқол дода мешаванд). Мо чунин мушкилот надорем - мо танҳо рақамҳоро интиқол медиҳем. Аммо агар шумо an objectҳоро интиқол диҳед, дар бораи он фаромӯш накунед!
  3. Баъд аз ин, он усули дилхоҳро даъват мекунад.
UnicastRemoteObject.exportObject()Мо an objectи ҳисобкунаки serverи худро ба усул мегузарем . Бо ин роҳ мо имкон медиҳем, ки усулҳои онро фосилаи дур даъват кунем. Мо танҳо як коре дорем:
registry.bind(UNIQUE_BINDING_NAME, stub);
Мо ноустувори худро дар феҳристи an objectҳои дурдаст бо номе, ки дар ибтидо пайдо карда будем, “қайд мекунем”. Акнун муштарӣ метавонад онро пайдо кунад! Шумо шояд пай бурда бошед, ки дар охир мо риштаи асосии барномаро ба хоб мегузорем:
Thread.sleep(Integer.MAX_VALUE);
Мо танҳо бояд serverро барои муддати тӯлонӣ кор кунем. Мо дар IDEa якбора ду усулро иҷро мекунем main(): аввал server (дар синфе, ки ServerMainмо аллакай навишта будем) ва баъд муштарӣ (дар синф ClientMainмо дар зер менависем). Муҳим аст, ки барномаи server ҳангоми ба кор андохтани муштарӣ хомӯш нашавад, аз ин рӯ мо онро танҳо барои муддати тӯлонӣ дар хоб мегузорем. Он то ҳол кор хоҳад кард :) Акнун мо метавонем main()усули serverи худро иҷро кунем. Бигзор он кор кунад ва интизор шавад, ки барномаи муштарӣ ягон усулро даъват кунад :) Акнун биёед як барномаи муштарӣ нависем! Он рақамҳоро ба serverи мо мефиристад, то афзоиш ёбад.
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);
   }
}
Вай беасос менамояд. Дар ин ҷо чӣ гап? Аввалан, муштарӣ бояд аз номи беназири an objectе огоҳ бошад, ки усулҳояшро аз фосилаи дур даъват мекунад. Аз ин рӯ, дар барномаи муштарӣ мо низ як тағирёбанда эҷод кардем.Дар public static final String UNIQUE_BINDING_NAME = "server.calculator"; оянда, дар метод main()мо ба реестри an objectҳои дурдаст дастрасӣ пайдо мекунем. Барои ин, мо бояд ба усул занг занем LocateRegistry.getRegistry()ва ба он рақами портеро, ки реестри мо дар барномаи ServerMain сохта шудааст, интиқол диҳем - порти 2732 (ин рақам барои мисол интихоб карда шудааст, шумо метавонед аз дигараш истифода баред):
final Registry registry = LocateRegistry.getRegistry(2732);
Акнун ба мо лозим меояд, ки an objectи дилхохро аз реестр гирем! Ин осон аст, зеро мо номи беназири ӯро медонем!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Ба намуди кастинг диққат диҳед. Мо an objectи ҳосилшударо ба интерфейс меандозем Calculator, на синфи мушаххас RemoteCalculationServer . Тавре ки мо дар оғози лексия гуфта будем, RMI ба истифодаи прокси асос ёфтааст, бинобар ин занги дурдаст танҳо барои усулҳои интерфейсҳо дастрас аст, на дарсҳо. Дар охир, мо ба таври фосилавӣ методро multiply()дар an objectи худ даъват мекунем ва натиҷаро дар консол чоп мекунем.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Мо усулро main()дар синф ServerMainкайҳо оғоз карда будем, вақти он расидааст, ки усулро main()дар барномаи муштарӣ оғоз кунем ClientMain! Натиҷаи консол: 600 Ҳамин аст! Барномаи мо (ҳатто ду!) вазифаи худро бомуваффақият иҷро кард :) Агар шумо вақт ва хоҳиш дошта бошед, шумо метавонед онро каме диверсификатсия кунед. Масалан, боварӣ ҳосил кунед, ки ҳисобкунак ҳамаи чор амалиёти стандартиро дастгирӣ мекунад, на рақамҳо, балки an object ҳамчун параметр интиқол дода мешавад CalculationInstance(int x, int y). Ҳамчун маводи иловагӣ, шумо метавонед ба мақолаҳо ва мисолҳо нигаред - дар ин ҷо: Дар дарсҳои оянда вохӯрем! :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION