CodeGym /Blog Java /rawak /RMI Jawa
John Squirrels
Tahap
San Francisco

RMI Jawa

Diterbitkan dalam kumpulan
Hai! Hari ini kita akan mempertimbangkan topik yang agak menarik: Java RMI. Ini bermaksud Invocation Kaedah Jauh. Anda boleh menggunakan RMI untuk membenarkan dua atur cara berkomunikasi antara satu sama lain, walaupun ia berada pada komputer yang berbeza. Adakah bunyi itu sejuk? :) Dan ia tidak begitu sukar untuk dilakukan! Dalam pelajaran hari ini, kami akan menganalisis elemen interaksi RMI dan memikirkan cara mengkonfigurasinya. Perkara pertama yang kita perlukan ialah klien dan pelayan. Kita sebenarnya tidak perlu mendalami istilah komputer. Apabila bercakap mengenai RMI, ini hanyalah dua program. Salah seorang daripada mereka akan memasukkan objek, dan yang lain akan memanggil kaedah pada objek itu. Kaedah memanggil objek yang wujud dalam program yang berbeza — sekarang itu sesuatu yang belum kami lakukan! Sudah tiba masanya untuk mencubanya! :) Untuk mengelak daripada terjebak, mari' s pastikan program kami mudah. Secara umum, pelayan melakukan beberapa pengiraan yang diminta oleh pelanggan. Dan begitu juga dengan kita. Pelayan kami akan menjadi program kalkulator mudah. Ia hanya akan mempunyai satu kaedah:darab() . Ia akan mendarabkan dua nombor yang dihantar kepadanya oleh program klien, dan kemudian mengembalikan hasilnya. Pertama sekali, kami 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? Kerana RMI bergantung pada mencipta proksi, yang anda pelajari dalam pelajaran lepas . Seperti yang anda mungkin ingat, kami bekerja dengan proksi melalui antara muka, bukan kelas. Terdapat 2 keperluan penting untuk antara muka kami!
  1. Ia mesti memanjangkan antara muka Jauh.
  2. Semua kaedahnya mesti membuang RemoteException (IDE tidak akan melakukan ini secara automatik - anda perlu menambah ini secara manual!).
Sekarang kita perlu mencipta kelas pelayan yang melaksanakan antara muka Kalkulator kami . RMI dalam amalan - 2Di sini juga, semuanya 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 ada apa-apa untuk diulas di sini :) Sekarang kita perlu menulis program pelayan yang akan mengkonfigurasi dan menjalankan objek kalkulator kita. 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 perkara ini :) Dalam baris pertama, kami mengisytiharkan beberapa pembolehubah String:

public static final String UNIQUE_BINDING_NAME = "server.calculator";
Rentetan ini ialah nama unik objek jauh. Program pelanggan kami menggunakan nama ini untuk mencari pelayan kami: anda akan melihatnya kemudian. Seterusnya, kami mencipta objek kalkulator kami:

final RemoteCalculationServer server = new RemoteCalculationServer();
Semuanya jelas di sini. Apa yang akan datang lebih menarik:

final Registry registry = LocateRegistry.createRegistry(2732);
Objek Pendaftaran ini ialah pendaftaran objek jauh. Ini adalah objek yang boleh diakses oleh program lain dari jauh :) Kami menghantar nombor 2732 kepada kaedah LocateRegistry.createRegistry() . Ini ialah nombor port — nombor unik yang akan digunakan oleh program lain untuk mencari pendaftaran objek kami (sekali lagi, anda akan melihatnya di bawah). Bergerak terus... Mari lihat apa yang berlaku dalam baris seterusnya:

Remote stub = UnicastRemoteObject.exportObject(server, 0);
Kami membuat stub dalam baris ini. Satu rintisan merangkum keseluruhan panggilan jauh. Anda boleh menganggap ini elemen terpenting RMI. Apa yang ia lakukan?
  1. Ia menerima semua maklumat tentang panggilan jauh beberapa kaedah.
  2. Jika kaedah tersebut mempunyai parameter, stub akan menyahsirikannya. Perhatikan perkara ini! Argumen yang anda hantar ke kaedah yang dipanggil dari jauh mestilah boleh bersiri (lagipun, ia akan dihantar melalui rangkaian). Ini tiada masalah untuk kami — kami hanya menghantar nombor. Tetapi jika anda menghantar objek, jangan lupa keperluan ini!
  3. Selepas itu, rintisan memanggil kaedah yang dikehendaki.
Kami menghantar objek pelayan kalkulator kami kepada kaedah UnicastRemoteObject.exportObject() . Ini adalah cara kami memungkinkan untuk memanggil kaedahnya dari jauh. Hanya ada 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 akan dapat mencarinya! Mungkin anda perasan bahawa kami meletakkan utas utama program untuk tidur pada penghujungnya:

Thread.sleep(Integer.MAX_VALUE);
Kami hanya memerlukan pelayan untuk berjalan untuk masa yang lama. Dalam IDE, kami akan melancarkan dua kaedah main() serentak : pertama, kaedah main() pelayan (dalam kelas ServerMain , yang telah kami tulis), dan kedua, kaedah main() klien (dalam kelas ClientMain , yang akan kami tulis di bawah). Adalah penting bahawa program pelayan tidak ditamatkan semasa kami memulakan klien, jadi kami hanya meletakkannya untuk masa yang lama. Walau apa pun, ia akan terus berjalan :) Sekarang kita boleh menjalankan kaedah main() 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 pendaraban.

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);
   }
}
Nampak simple je. Tetapi apa yang berlaku di sini? Pertama, pelanggan mesti mengetahui nama unik objek yang kaedahnya akan dipanggil dari jauh. Oleh itu, dalam program klien, kami mencipta String akhir statik awam UNIQUE_BINDING_NAME = "server.calculator"; pembolehubah. Seterusnya, dalam kaedah main() , kita mendapat akses kepada daftar objek jauh. Untuk melakukan ini, kami perlu memanggil kaedah LocateRegistry.getRegistry() dan lulus nombor port yang digunakan untuk mencipta pendaftaran kami dalam program ServerMain (port 2732; nombor ini hanyalah contoh — anda boleh cuba menggunakan nombor lain):

final Registry registry = LocateRegistry.getRegistry(2732);
Sekarang kita hanya perlu mendapatkan objek yang diingini daripada pendaftaran! Ini mudah, kerana kami tahu namanya yang unik!

Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Beri perhatian kepada pemutus jenis. Kami menghantar objek yang diterima ke antara muka Kalkulator , bukan ke kelas RemoteCalculationServer . Seperti yang kami katakan pada permulaan pelajaran, RMI bergantung pada proksi, jadi panggilan jauh hanya tersedia untuk kaedah antara muka, bukan kaedah kelas. Akhir sekali, kami memanggil kaedah multiply() dari jauh pada objek kami dan mengeluarkan hasilnya ke konsol.

int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Kaedah main() kelas ServerMain telah pun berjalan untuk masa yang lama. Kini tiba masanya untuk menjalankan kaedah main() dalam program klien ( ClientMain )! Output konsol:

600
Itu sahaja! Program kami (dua program, sebenarnya!) melakukan apa yang sepatutnya dilakukan :) Jika anda mempunyai masa dan keinginan, anda boleh menceriakan ini sedikit. Contohnya, jadikan kalkulator menyokong empat operasi aritmetik standard, dan hantar nombor bukan sebagai jenis primitif, tetapi sebagai objek CalculationInstance(int x, int y) . Jumpa anda dalam pelajaran seterusnya! :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION