JavaRush /Java блогы /Random-KK /RMI: қолдану тәжірибесі

RMI: қолдану тәжірибесі

Топта жарияланған
Сәлеметсіз бе! Бүгін біз өте қызықты тақырыпты қарастырамыз - RMI . Бұл қашықтағы әдісті шақыру дегенді білдіреді . RMI: қолдану тәжірибесі - 1RMI көмегімен сіз екі бағдарламаны, тіпті олар әртүрлі компьютерлерде болса да, бір-бірімен байланысуға үйрете аласыз. Керемет естіледі ме? :) Бірақ мұны істеу соншалықты қиын емес! Бүгінгі дәрісте біз RMI өзара әрекеттесуінің қандай бөліктерден тұратынын және оны қалай конфигурациялау керектігін түсінеміз. Бізге қажет бірінші нәрсе - клиент пен server . Компьютерлік терминологияға тым тереңдеудің қажеті жоқ. RMI жағдайында бұл жай ғана екі бағдарлама. Олардың біреуінде қандай да бір 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 жұмысы сіз алдыңғы лекциялардың бірінде оқыған прокси-serverлерді құруға негізделген . Ал прокси-serverлермен жұмыс, есіңізде болса керек, сыныптар емес, дәл интерфейстер деңгейінде жүзеге асырылады. Біздің интерфейсімізге 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";
Бұл жол қашықтағы нысанның бірегей атауы болып табылады . Осы атаумен клиенттік бағдарлама біздің serverді таба алады: оны кейінірек көресіз. Содан кейін біз калькулятор an objectісін жасаймыз:
final RemoteCalculationServer server = new RemoteCalculationServer();
Мұнда бәрі түсінікті. Келесі қызықтырақ:
final Registry registry = LocateRegistry.createRegistry(2732);
Бұл Registry деп аталатын нәрсе жойылған нысандардың тізілімі болып табылады . «Жойылды» біз оларды компьютерден жойдық деген мағынада емес, бірақ бұл регистрдегі нысандарға басқа бағдарламалардан қашықтан қол жеткізуге болады :) LocateRegistry.createRegistry()Біз әдіске 2732 нөмірін бердік.Бұл порт нөмірі. Егер сіз порттың не екенін білмесеңіз, оны мына жерден оқи аласыз , бірақ әзірге бұл басқа бағдарламалар біздің нысандар тізілімін таба алатын бірегей нөмір екенін есте сақтаңыз (оны төменде де көресіз). Әрі қарай жүрейік. Келесі жолда не болатынын көрейік:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Бұл жолда біз түтік жасаймыз . Қоңырау шалу қашықтан қоңырау шалу процесін өз ішінде қамтиды. Бұл RMI ең маңызды элементі деп айтуға болады . Ол не істеп жатыр?
  1. Әдіске қашықтан қоңырау шалу туралы барлық ақпаратты алады.
  2. Егер әдістің параметрлері болса, тірек оларды сериядан шығарады. Осы жайтқа назар аударыңыз! Қашықтағы қоңырауларға арналған әдістерге берілетін параметрлер серияланатын болуы керек (ақыр соңында олар желі арқылы тасымалданады). Бізде мұндай проблема жоқ - біз тек сандарды жібереміз. Бірақ егер сіз нысандарды тасымалдасаңыз, бұл туралы ұмытпаңыз!
  3. Осыдан кейін ол қажетті әдісті шақырады.
UnicastRemoteObject.exportObject()Біз 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);
   }
}
Ол күрделі емес көрінеді. Мұнда не болып жатыр? Біріншіден, клиент әдістері қашықтан шақырылатын нысанның бірегей атауын білуі керек. Сондықтан клиенттік бағдарламада біз айнымалыны да жасадық.Келесі public static final String UNIQUE_BINDING_NAME = "server.calculator"; әдісте main()қашықтағы an objectілер регистріне қол жеткіземіз. Бұл әрекетті орындау үшін әдісті шақырып, LocateRegistry.getRegistry()сол жерге тізілім ServerMain бағдарламасында жасалған порт нөмірін беру керек - 2732 порт (бұл нөмір мысал үшін таңдалған, сіз басқасын пайдаланып көріңіз):
final Registry registry = LocateRegistry.getRegistry(2732);
Енді бізге қажетті нысанды регистрден алу ғана қалды! Бұл оңай, өйткені біз оның ерекше есімін білеміз!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Типке назар аударыңыз. Алынған нысанды нақты сыныпқа емес интерфейскеCalculator шығардық RemoteCalculationServer. Дәріс басында айтқанымыздай, RMI прокси-serverді пайдалануға негізделген, сондықтан қашықтан қоңырау шалу сыныптарға емес, интерфейстердің әдістеріне ғана қол жетімді. Соңында біз multiply()an objectіміздегі әдісті қашықтан шақырамыз және нәтижені консольге басып шығарамыз.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Біз әдісті main()сыныпта ServerMainбұрыннан іске қостық, әдісті main()клиенттік бағдарламада іске қосу уақыты келді ClientMain! Консоль шығысы: 600 Міне, солай! Біздің бағдарлама (тіпті екі!) өз функциясын сәтті орындады :) Егер сізде уақыт пен тілек болса, оны аздап әртараптандыруға болады. Мысалы, калькулятор сандарды емес, барлық төрт стандартты операцияны қолдайтынын, бірақ параметр ретінде нысан жіберілетінін тексеріңіз CalculationInstance(int x, int y). Қосымша материал ретінде сіз мақалалар мен мысалдарды көре аласыз - мұнда: Келесі сабақтарда кездескенше! :)
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION