JavaRush /Java Blogu /Random-AZ /RMI: istifadə təcrübəsi

RMI: istifadə təcrübəsi

Qrupda dərc edilmişdir
Salam! Bu gün biz olduqca maraqlı bir mövzuya baxacağıq - RMI . Bu Remote Method Invocation deməkdir . RMI: istifadə təcrübəsi - 1RMI ilə siz iki proqramı müxtəlif kompüterlərdə olsalar belə, bir-biri ilə əlaqə qurmağı öyrədə bilərsiniz. Gözəl səslənir? :) Amma bunu etmək o qədər də çətin deyil! Bugünkü mühazirəmizdə RMI qarşılıqlı əlaqəsinin hansı hissələrdən ibarət olduğunu və onu necə konfiqurasiya edəcəyimizi anlayacağıq. Bizə lazım olan ilk şey müştəriserverdir . Kompüter terminologiyasına çox dərindən girmək lazım deyil. RMI vəziyyətində bunlar sadəcə iki proqramdır. Onlardan biri hansısa obyekti ehtiva edəcək, ikincisi isə bu obyektin metodlarını çağıracaq. Başqa bir proqramda yerləşən bir proqramdakı obyektin metodlarını çağırmaq - biz bunu əvvəllər heç vaxt etməmişik! Bunu sınamağın vaxtıdır! :) Vəhşi təbiətdə boğulmamaq üçün proqramımız sadə olsun. Ümumiyyətlə, serverlər adətən müştərinin tələb etdiyi bir növ hesablamalar aparırlar. Bizim üçün də belə olacaq. Server olaraq sadə kalkulyator proqramımız olacaq. Onun yalnız bir üsulu olacaq - multiply(). O, müştəri proqramı tərəfindən ona göndərilən iki rəqəmi çoxaldacaq və nəticəni qaytaracaq. Əvvəlcə bizə bir interfeys lazımdır:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Niyə bizə interfeys lazımdır? Fakt budur ki, RMI-nin işi əvvəlki mühazirələrdən birində oxuduğunuz proksilərin yaradılmasına əsaslanır . Və etibarnamələrlə iş, yəqin ki, xatırladığınız kimi, siniflər deyil, dəqiq interfeyslər səviyyəsində həyata keçirilir. İnterfeysimiz üçün 2 vacib tələb var!
  1. O, Uzaqdan Token interfeysini miras almalıdır.
  2. Onun bütün üsulları RemoteException atmalıdır (bu, IDE-də avtomatik olaraq edilmir, onu əl ilə yazmalısınız!).
İndi interfeysimizi həyata keçirəcək bir server sinfi yaratmalıyıq Calculator. RMI: istifadə təcrübəsi - 2Burada hər şey olduqca sadədir:
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

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

}
Burada şərh etmək üçün çox şey yoxdur :) İndi biz server kalkulyator sinifimizi konfiqurasiya edəcək və işə salacaq bir server proqramı yazmalıyıq. Bu belə görünəcək:
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);

   }
}
Gəlin bunu anlayaq :) Birinci sətirdə bir növ sətir dəyişəni yaradırıq:
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Bu sətir uzaq obyektin unikal adıdır . Bu adla müştəri proqramı bizim serverimizi tapa biləcək: siz bunu daha sonra görəcəksiniz. Sonra kalkulyator obyektimizi yaradırıq:
final RemoteCalculationServer server = new RemoteCalculationServer();
Burada hər şey aydındır. Aşağıdakılar daha maraqlıdır:
final Registry registry = LocateRegistry.createRegistry(2732);
Registry adlı bu şey silinmiş obyektlərin reyestridir . “Silindi” onları kompüterdən sildiyimiz mənasında deyil, bu registrdəki obyektlərə digər proqramlardan uzaqdan daxil olmaq mümkün olması baxımından :) LocateRegistry.createRegistry()Metodun üzərinə 2732 nömrəsini keçirdik.Bu port nömrəsidir. Əgər portun nə olduğunu bilmirsinizsə, onu burada oxuya bilərsiniz , lakin hələlik bu, digər proqramların obyekt reyestrimizi tapa biləcəyi unikal nömrə olduğunu xatırlamalısınız (bunu aşağıda da görəcəksiniz). Gəlin davam edək. Növbəti sətirdə nə baş verdiyinə baxaq:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Bu xəttdə bir stub yaradırıq . Bir stub bütün uzaqdan zəng prosesini özündə cəmləşdirir. Bunun RMI-nin ən vacib elementi olduğunu söyləmək olar . O nə edir?
  1. Bir metoda uzaqdan zəng haqqında bütün məlumatları alır.
  2. Metodun parametrləri varsa, stub onları sıradan çıxarır. Bu məqama diqqət yetirin! Uzaqdan zənglər üçün metodlara ötürdüyünüz parametrlər seriallaşdırıla bilən olmalıdır (hər şeydən sonra onlar şəbəkə üzərindən ötürüləcək). Bizim belə bir problemimiz yoxdur - sadəcə nömrələri ötürürük. Ancaq obyektləri köçürsəniz, bu barədə unutmayın!
  3. Bundan sonra o, istədiyiniz metodu çağırır.
UnicastRemoteObject.exportObject()Biz server kalkulyator obyektimizi metoda keçirik . Bu yolla biz onun metodlarını uzaqdan çağırmağı mümkün edirik. Yalnız bir işimiz qalıb:
registry.bind(UNIQUE_BINDING_NAME, stub);
Biz stubumuzu uzaq obyektlərin reyestrində əvvəldən tapdığımız adla “qeyd edirik”. İndi müştəri onu tapa bilər! Sonda proqramın əsas mövzusunu yuxu rejiminə qoyduğumuzu görmüsünüz:
Thread.sleep(Integer.MAX_VALUE);
Sadəcə, serveri uzun müddət işlək vəziyyətdə saxlamalıyıq. IDEa-da eyni anda iki metodu işlədəcəyik : əvvəlcə server biri ( daha əvvəl yazdığımız main()sinifdə ), sonra isə müştəri (sinfdə aşağıda yazacağıq). Müştərini işə salarkən server proqramının sönməməsi vacibdir, ona görə də biz onu sadəcə olaraq uzun müddət yuxu rejiminə qoyuruq. Hələ də işləyəcək :) İndi server metodumuzu işlədə bilərik. Çalışsın və müştəri proqramının hansısa metodu çağırmasını gözləyin :) İndi müştəri proqramı yazaq! Çoxalmaq üçün nömrələri serverimizə göndərəcək. ServerMainClientMainmain()
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);
   }
}
O, sadə görünür. Burda nə baş verir? Birincisi, müştəri metodlarını uzaqdan çağıracağı obyektin unikal adından xəbərdar olmalıdır. Buna görə də klient proqramında biz də dəyişən yaratdıq.Sonrakı public static final String UNIQUE_BINDING_NAME = "server.calculator"; , metodda main()biz uzaq obyektlərin registrinə giriş əldə edirik. Bunu etmək üçün metodu çağırmalı LocateRegistry.getRegistry()və ServerMain proqramında reyestrimizin yaradıldığı port nömrəsini - port 2732 (bu nömrə nümunə üçün seçilmişdir, başqasından istifadə etməyə cəhd edə bilərsiniz) ora keçməliyik:
final Registry registry = LocateRegistry.getRegistry(2732);
İndi bizə sadəcə registrdən istədiyiniz obyekti əldə etmək qalır! Bu asandır, çünki biz onun unikal adını bilirik!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Döküm növünə diqqət yetirin. Nəticə olan obyekti konkret sinifdən çox interfeysəCalculator köçürdük RemoteCalculationServer. Mühazirənin əvvəlində dediyimiz kimi, RMI proksinin istifadəsinə əsaslanır, ona görə də uzaqdan çağırış siniflər üçün deyil, yalnız interfeys metodları üçün mövcuddur. Sonda multiply()obyektimizdə uzaqdan metod çağırırıq və nəticəni konsolda çap edirik.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Biz metodu main()sinifdə ServerMainçoxdan işə saldıq, main()müştəri proqramında metodu işə salmağın vaxtı gəldi ClientMain! Konsol çıxışı: 600 Budur! Proqramımız (hətta iki!) öz funksiyasını uğurla yerinə yetirdi :) Vaxtınız və istəyiniz varsa, onu bir az diversifikasiya edə bilərsiniz. Məsələn, kalkulyatorun rəqəmlər deyil, hər dörd standart əməliyyatı dəstəklədiyinə əmin olun, lakin parametrlər kimi obyekt ötürülür CalculationInstance(int x, int y). Əlavə material olaraq məqalələrə və nümunələrə baxa bilərsiniz - burada: Növbəti dərslərdə görüşənədək! :)
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION