JavaRush /Blog Java /Random-MS /RMI: amalan penggunaan

RMI: amalan penggunaan

Diterbitkan dalam kumpulan
hello! Hari ini kita akan melihat topik yang agak menarik - RMI . Ini bermaksud Invocation Kaedah Jauh . RMI: amalan penggunaan - 1Dengan RMI, anda boleh mengajar dua program untuk berkomunikasi antara satu sama lain, walaupun ia berada pada komputer yang berbeza. Kedengaran sejuk? :) Tetapi ia tidak begitu sukar untuk dilakukan! Dalam kuliah hari ini, kita akan memahami bahagian interaksi RMI dan bagaimana untuk mengkonfigurasinya. Perkara pertama yang kita perlukan ialah pelanggan dan pelayan . Anda tidak perlu mendalami istilah komputer. Dalam kes RMI, ini hanyalah dua program. Salah satu daripadanya akan mengandungi beberapa objek, dan yang kedua akan memanggil kaedah objek ini. Kaedah memanggil objek dalam satu program yang terletak dalam program lain - kami tidak pernah melakukan ini sebelum ini! Sudah tiba masanya untuk mencubanya! :) Untuk tidak lemas di alam liar, biarlah program kami sederhana. Secara umum, pelayan biasanya menjalankan beberapa jenis pengiraan yang diminta oleh pelanggan. Ia akan sama untuk kita. Kami akan mempunyai program kalkulator mudah sebagai pelayan. Dia hanya mempunyai satu kaedah - multiply(). Ia akan mendarabkan dua nombor yang dihantar kepadanya oleh program klien dan mengembalikan hasilnya. Pertama sekali kita memerlukan antara muka:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Mengapa kita memerlukan antara muka? Hakikatnya ialah kerja RMI adalah berdasarkan mencipta proksi, yang anda pelajari dalam salah satu kuliah sebelumnya . Dan bekerja dengan proksi, seperti yang anda mungkin ingat, dijalankan dengan tepat pada tahap antara muka, bukan kelas. Terdapat 2 keperluan penting untuk antara muka kami!
  1. Ia mesti mewarisi antara muka token Jauh.
  2. Semua kaedahnya mesti membuang RemoteException (ini tidak dilakukan secara automatik dalam IDE, anda perlu menulisnya secara manual!).
Sekarang kita perlu mencipta kelas pelayan yang akan melaksanakan antara muka kita Calculator. RMI: amalan penggunaan - 2Segala-galanya di sini juga agak mudah:
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

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

}
Tidak banyak yang perlu diulas di sini :) Sekarang kita perlu menulis program pelayan yang akan mengkonfigurasi dan melancarkan kelas kalkulator pelayan kami. Ia akan kelihatan seperti ini:
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);

   }
}
Mari kita fikirkan :) Dalam baris pertama kita mencipta beberapa jenis pembolehubah rentetan:
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Rentetan ini ialah nama unik objek jauh . Dengan nama ini program klien akan dapat mencari pelayan kami: anda akan melihatnya kemudian. Seterusnya kami mencipta objek kalkulator kami:
final RemoteCalculationServer server = new RemoteCalculationServer();
Semuanya jelas di sini. Yang berikut lebih menarik:
final Registry registry = LocateRegistry.createRegistry(2732);
Perkara yang dipanggil Registry ini ialah pendaftaran objek yang dipadam . "Dipadamkan" bukan dalam erti kata bahawa kami memadamkannya dari komputer, tetapi pada hakikatnya objek dari daftar ini boleh diakses dari jauh dari program lain :) LocateRegistry.createRegistry()Kami menghantar nombor 2732 kepada kaedah. Ini adalah nombor port. Jika anda tidak tahu apa itu port, anda boleh membacanya di sini , tetapi buat masa ini anda hanya perlu ingat bahawa ini adalah nombor unik yang mana program lain boleh mencari pendaftaran objek kami (anda juga akan melihatnya di bawah). Jom teruskan. Mari lihat apa yang berlaku dalam baris seterusnya:
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Pada baris ini kita mencipta rintisan . Rintisan merangkum keseluruhan proses panggilan jauh dalam dirinya sendiri. Boleh dikatakan ini adalah elemen terpenting dalam RMI. Apa yang dia sedang buat?
  1. Menerima semua maklumat tentang panggilan jauh ke kaedah.
  2. Jika kaedah tersebut mempunyai parameter, stub akan menyahsirikannya. Perhatikan perkara ini! Parameter yang anda hantar ke kaedah untuk panggilan jauh mestilah boleh bersiri (lagipun, ia akan dihantar melalui rangkaian). Kami tidak mempunyai masalah sedemikian - kami hanya menghantar nombor. Tetapi jika anda memindahkan objek, jangan lupa tentangnya!
  3. Selepas itu, ia memanggil kaedah yang dikehendaki.
Kami menghantar UnicastRemoteObject.exportObject()objek kalkulator pelayan kami kepada kaedah. Dengan cara ini kami memungkinkan untuk memanggil kaedahnya dari jauh. Kami hanya mempunyai satu perkara yang perlu dilakukan:
registry.bind(UNIQUE_BINDING_NAME, stub);
Kami "mendaftar" stub kami dalam pendaftaran objek jauh di bawah nama yang kami buat pada awalnya. Kini pelanggan boleh menemuinya! Anda mungkin perasan bahawa pada akhirnya kami meletakkan utas utama program untuk tidur:
Thread.sleep(Integer.MAX_VALUE);
Kami hanya perlu memastikan pelayan berjalan untuk masa yang lama. Kami akan menjalankan dua kaedah dalam IDEa sekaligus main(): pertama pelayan satu (dalam kelas ServerMainyang telah kami tulis), dan kemudian klien (dalam kelas ClientMainkami akan tulis di bawah). Adalah penting bahawa program pelayan tidak turun semasa kami melancarkan klien, jadi kami hanya meletakkannya untuk masa yang lama. Ia masih akan berfungsi :) Kini kami boleh menjalankan main()kaedah pelayan kami. Biarkan ia berjalan dan tunggu program klien memanggil beberapa kaedah :) Sekarang mari tulis program klien! Ia akan menghantar nombor ke pelayan kami untuk didarab.
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);
   }
}
Dia kelihatan tidak rumit. Apa yang berlaku di sini? Pertama, pelanggan mesti mengetahui nama unik objek yang kaedahnya akan dipanggil dari jauh. Oleh itu, dalam program klien kami juga mencipta pembolehubah. public static final String UNIQUE_BINDING_NAME = "server.calculator"; Seterusnya, dalam kaedah main()kami mendapat akses kepada daftar objek jauh. Untuk melakukan ini, kami perlu memanggil kaedah LocateRegistry.getRegistry()dan menghantar nombor port di mana daftar kami dibuat dalam program ServerMain - port 2732 (nombor ini dipilih sebagai contoh, anda boleh cuba menggunakan yang lain):
final Registry registry = LocateRegistry.getRegistry(2732);
Sekarang apa yang perlu kita lakukan ialah mendapatkan objek yang diingini daripada daftar! Mudah sahaja kerana kita tahu nama uniknya!
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Beri perhatian kepada pemutus jenis. Kami menghantar objek yang terhasil ke antara muka Calculatordan bukannya kelas konkrit RemoteCalculationServer . Seperti yang kami katakan pada permulaan kuliah, RMI adalah berdasarkan penggunaan proksi, jadi panggilan jauh hanya tersedia untuk kaedah antara muka, bukan kelas. Pada akhirnya, kami memanggil kaedah dari jauh multiply()pada objek kami dan mencetak hasilnya ke konsol.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Kami melancarkan kaedah main()dalam kelas ServerMainlama dahulu, sudah tiba masanya untuk melancarkan kaedah main()dalam program klien ClientMain! Output konsol: 600 Itu sahaja! Program kami (walaupun dua!) berjaya memenuhi fungsinya :) Jika anda mempunyai masa dan keinginan, anda boleh mempelbagaikannya sedikit. Contohnya, pastikan kalkulator menyokong keempat-empat operasi standard, dan bukan nombor, tetapi objek diluluskan sebagai parameter CalculationInstance(int x, int y). Sebagai bahan tambahan, anda boleh melihat artikel dan contoh - di sini: Jumpa lagi di kelas akan datang! :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION