JavaRush /Java blogi /Random-UZ /RMI: foydalanish amaliyoti

RMI: foydalanish amaliyoti

Guruhda nashr etilgan
Salom! Bugun biz juda qiziqarli mavzuni ko'rib chiqamiz - RMI . Bu masofaviy usul chaqiruvini anglatadi . RMI: foydalanish amaliyoti - 1RMI yordamida siz ikkita dasturni turli xil kompyuterlarda bo'lsa ham, bir-biri bilan muloqot qilishni o'rgatishingiz mumkin. Ajoyib eshitiladimi? :) Lekin buni qilish unchalik qiyin emas! Bugungi ma'ruzada biz RMI o'zaro ta'siri qaysi qismlardan iboratligini va uni qanday sozlashni tushunamiz. Bizga kerak bo'lgan birinchi narsa - mijoz va server . Kompyuter terminologiyasiga juda chuqur kirib borish shart emas. RMI bo'lsa, bu shunchaki ikkita dastur. Ulardan biri qandaydir ob'ektni o'z ichiga oladi, ikkinchisi esa ushbu ob'ektning usullarini chaqiradi. Boshqa dasturda joylashgan bitta dasturdagi ob'ektning usullarini chaqirish - biz ilgari hech qachon bunday qilmaganmiz! Buni sinash vaqti keldi! :) Yovvoyi tabiatda cho'kib ketmaslik uchun dasturimiz sodda bo'lsin. Umuman olganda, serverlar odatda mijoz so'ragan hisob-kitoblarni amalga oshiradilar. Biz uchun ham xuddi shunday bo'ladi. Biz server sifatida oddiy kalkulyator dasturiga ega bo'lamiz. Uning faqat bitta usuli bo'ladi - multiply(). U mijoz dasturi tomonidan yuborilgan ikkita raqamni ko'paytiradi va natijani qaytaradi. Bizga birinchi navbatda interfeys kerak:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Nima uchun bizga interfeys kerak? Gap shundaki, RMI ishi siz oldingi ma'ruzalardan birida o'qigan proksi-serverlarni yaratishga asoslangan . Va proksi-serverlar bilan ishlash, ehtimol siz eslayotganingizdek, sinflar emas, balki interfeyslar darajasida amalga oshiriladi. Bizning interfeysimiz uchun ikkita muhim talab mavjud!
  1. U Remote token interfeysini meros qilib olishi kerak.
  2. Uning barcha usullari RemoteException-ni tashlashi kerak (bu IDE-da avtomatik ravishda amalga oshirilmaydi, uni qo'lda yozishingiz kerak!).
Endi biz interfeysimizni amalga oshiradigan server sinfini yaratishimiz kerak Calculator. RMI: foydalanish amaliyoti - 2Bu erda hamma narsa juda oddiy:
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

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

}
Bu yerda sharhlash uchun ko'p narsa yo'q :) Endi biz server kalkulyator sinfimizni sozlaydigan va ishga tushiradigan server dasturini yozishimiz kerak. Bu shunday ko'rinadi:
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);

   }
}
Keling, buni aniqlaymiz :) Birinchi qatorda biz qandaydir string o'zgaruvchini yaratamiz:
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Ushbu qator uzoq ob'ektning noyob nomidir . Ushbu nom bilan mijoz dasturi bizning serverimizni topa oladi: buni keyinroq ko'rasiz. Keyin biz kalkulyator ob'ektimizni yaratamiz:
final RemoteCalculationServer server = new RemoteCalculationServer();
Bu erda hamma narsa aniq. Quyidagilar qiziqroq:
final Registry registry = LocateRegistry.createRegistry(2732);
Ro'yxatga olish kitobi deb ataladigan bu narsa o'chirilgan ob'ektlar ro'yxatidir . "O'chirildi" biz ularni kompyuterdan o'chirib tashlaganimiz ma'nosida emas, balki ushbu registrdagi ob'ektlarga boshqa dasturlardan masofadan kirish mumkinligida :) LocateRegistry.createRegistry()Biz 2732 raqamini usulga o'tkazdik.Bu port raqami. Agar siz port nima ekanligini bilmasangiz, uni bu yerda o'qishingiz mumkin , ammo hozircha bu noyob raqam ekanligini yodda tutishingiz kerak, bu boshqa dasturlar bizning ob'ektlar registrini topa oladi (siz buni quyida ham ko'rasiz). Keling, davom etaylik. Keling, keyingi qatorda nima sodir bo'lishini ko'rib chiqaylik:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Ushbu chiziqda biz stub hosil qilamiz . Stub butun masofaviy qo'ng'iroq jarayonini o'zida qamrab oladi. Aytish mumkinki, bu RMI ning eng muhim elementi . U nima qilyapti?
  1. Usulga masofaviy qo'ng'iroq haqida barcha ma'lumotlarni oladi.
  2. Agar usul parametrlarga ega bo'lsa, stub ularni seriyadan chiqaradi. Bu nuqtaga e'tibor bering! Masofaviy qo'ng'iroqlar usullariga o'tadigan parametrlar seriyali bo'lishi kerak (axir ular tarmoq orqali uzatiladi). Bizda bunday muammo yo'q - biz faqat raqamlarni uzatamiz. Ammo agar siz ob'ektlarni o'tkazsangiz, bu haqda unutmang!
  3. Shundan so'ng, u kerakli usulni chaqiradi.
UnicastRemoteObject.exportObject()Biz server kalkulyator ob'ektimizni usulga o'tkazamiz . Shunday qilib, biz uning usullarini masofadan turib chaqirish imkoniyatini yaratamiz. Bizda faqat bitta ish qoldi:
registry.bind(UNIQUE_BINDING_NAME, stub);
Biz stubimizni uzoqdagi ob'ektlar registrida boshida o'ylab topilgan nom bilan "ro'yxatdan o'tkazamiz". Endi mijoz uni topa oladi! Oxir-oqibat biz dasturning asosiy qismini uyqu rejimiga qo'yganimizni payqagan bo'lishingiz mumkin:
Thread.sleep(Integer.MAX_VALUE);
Biz faqat serverni uzoq vaqt ishlashini ta'minlashimiz kerak. Biz IDEa-da bir vaqtning o'zida ikkita usulni ishga tushiramiz main(): birinchi navbatda server (biz allaqachon yozgan sinfda ServerMain), keyin esa mijoz (sinfda ClientMainbiz quyida yozamiz). Mijozni ishga tushirayotganda server dasturi ishlamay qolishi muhim, shuning uchun biz uni uzoq vaqt uyqu rejimiga qo'yamiz. U hali ham ishlaydi :) Endi biz main()server usulimizni ishga tushirishimiz mumkin. Ishlayvering va mijoz dasturi qandaydir usulni chaqirishini kuting :) Endi mijoz dasturini yozamiz! U ko'paytirish uchun raqamlarni serverimizga yuboradi.
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);
   }
}
U oddiy ko'rinadi. Bu yerda nima bo'lyapti? Birinchidan, mijoz ob'ektning noyob nomini bilishi kerak, uning usullari masofadan turib chaqiriladi. Shuning uchun mijoz dasturida biz ham o'zgaruvchi yaratdik.Keyingi public static final String UNIQUE_BINDING_NAME = "server.calculator"; usulda main()biz masofaviy ob'ektlar registriga kirish huquqiga ega bo'lamiz. Buni amalga oshirish uchun biz usulni chaqirishimiz LocateRegistry.getRegistry()va u erda ServerMain dasturida registrimiz yaratilgan port raqamini o'tkazishimiz kerak - port 2732 (bu raqam misol uchun tanlangan, siz boshqasidan foydalanishga harakat qilishingiz mumkin):
final Registry registry = LocateRegistry.getRegistry(2732);
Endi biz faqat kerakli ob'ektni registrdan olishimiz kerak! Bu oson, chunki biz uning noyob ismini bilamiz!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Kasting turiga e'tibor bering. Olingan ob'ektni aniq sinfga emas, balki interfeysgaCalculator o'tkazamiz RemoteCalculationServer. Ma'ruza boshida aytganimizdek, RMI proksi-serverdan foydalanishga asoslangan, shuning uchun masofaviy qo'ng'iroq faqat sinflar uchun emas, balki interfeys usullari uchun mavjud. Oxir-oqibat, biz multiply()ob'ektimizdagi usulni masofadan chaqiramiz va natijani konsolga chop etamiz.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Biz uslubni main()sinfda ServerMainancha oldin ishga tushirgan edik, main()mijoz dasturida usulni ishga tushirish vaqti keldi ClientMain! Konsol chiqishi: 600 Hammasi! Bizning dasturimiz (hatto ikkita!) o'z vazifasini muvaffaqiyatli bajardi :) Agar vaqt va xohishingiz bo'lsa, uni biroz diversifikatsiya qilishingiz mumkin. Misol uchun, kalkulyator raqamlarni emas, balki barcha to'rtta standart operatsiyani qo'llab-quvvatlashiga ishonch hosil qiling, lekin parametrlar sifatida ob'ekt uzatiladi CalculationInstance(int x, int y). Qo'shimcha material sifatida siz maqolalar va misollarni ko'rishingiz mumkin - bu erda: Keyingi darslarda ko'rishguncha! :)
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION