25/05/2018, 09:33

Xây dựng một ứng dụng phân tán với RMI

Xây dụng một ứng dụng phân tán bằng cơ chế RMI gồm các bước sau: Thiết kế và cài đặt các thành phần của ứng dụng. Biên dịch các chương trình nguồn và tạo ra Stub và Skeleton. Tạo các lớp có thể truy xuất từ mạng ...

Xây dụng một ứng dụng phân tán bằng cơ chế RMI gồm các bước sau: 

  1. Thiết kế và cài đặt các thành phần của ứng dụng.
  2. Biên dịch các chương trình nguồn và tạo ra Stub và Skeleton.
  3. Tạo các lớp có thể truy xuất từ mạng cần thiết.
  4. Khởi tạo ứng dụng

Thiết kế và cài đặt các thành phần của ứng dụng.

Đầu tiên bạn phải xác định lớp nào là lớp cục bộ, lớp nào là lớp được gọi từ xa. Nó bao gồm các bước sau:

  • Định nghĩa các giao diện cho các phương thức ở xa (remote interfaces): Một remote interface mô tả các phương thức mà nó có thể được kích hoạt từ xa bởi các Client. Đi cùng với việc định nghĩa Remote Interface là việc xác định các lớp cục bộ làm tham số hay giá trị trả về của các phương thức được gọi từ xa.
  • Cài đặt các đối tượng từ xa (remote objects): Các Remote Object phải cài đặt cho một hoặc nhiều Remote Interfaces đã được định nghĩa. Các lớp của  Remote Object class cài đặt cho các phương thức được gọi từ xa đã được khai báo trong Remote Interface và có thể định nghĩa và cài đặt cho cả các phương thức được sử dụng cục bộ. Nếu có các lớp làm đối số hay giá trị trả về cho các phương thức được gọi từ xa thì ta cũng định nghĩa và cài đặt chúng.
  • Cài đặt các chương trình Client: Các chương trình Client có sử dụng các Remote Object có thể được cài đặt ở bất kỳ thời điểm nào sau khi các Remote Interface đã được định nghĩa.

Biên dịch các tập tin nguồn và tạo Stubs và Skeleton

Giai đoạn này gồm 2 bước: Bước thứ nhất là dùng chương trình biên dịch javac để biên dịch các tập tin nguồn như các remote interface, các lớp cài đặt cho các remote interface, lớp server, lớp client và các lớp liên quan khác. Kế tiếp ta dùng trình biện dịch rmic để tạo ra stub và skeleton cho các đối tượng từ xa từ các lớp cài đặt cho các remote interface.

Tạo các lớp có thể truy xuất từ mạng

Tạo một tập tin chứa tất cả các file có liên quan như các remote interface stub, các lớp hỗ trợ mà chúng cần thiết phải tải về Client  và làm cho tập tin này có thể truy cập đến thông qua một Web server.

Thực thi ứng dụng

Thực thi ứng dụng bao gồm việc thực thi rmiregistry server, thực thi server, và thực thi client.

Tóm lại các công việc phải làm là:

  • Tạo giao diện (interface) khai báo các phương thức được gọi từ xa của đối tượng.
  • Tạo lớp cài đặt (implement) cho giao diện đã được khai báo.
  • Viết chương trình Server.
  • Viết chương trình Client.
  • Dịch các tập tin nguồn theo dạng RMI để tạo ra các lớp tương ứng và stub cho client, skeleton cho server.
  • Khởi động dịch vụ registry.
  • Thực hiện chương trình Server.
  • Thực thi chương trình Client.

Ví dụ minh họa

Trong ví dụ này chúng ta định nghĩa một phương thức String sayHello() được gọi từ xa. Mỗi khi phương thức này được kích hoạt nó sẽ trả về chuỗi "Hello World" cho Client gọi nó.

Dưới đây là các bước để xây dựng ứng dụng:

Bước 01: Tạo giao diện (interface) khai báo các phương thức được gọi từ xa của đối tượng. 

  • Cú pháp tổng quát:

import java.rmi.Remote;import java.rmi.RemoteException;public interface InterfaceName extends Remote {    ReturnType remoteMethodOne() throws RemoteException;    ReturnType remoteMethodTwo() throws RemoteException;     . . .}

  • Định nghĩa remote interface có tên là HelloItf, có phương thức được gọi từ xa là String sayHello() như sau:

import java.rmi.Remote;import java.rmi.RemoteException;public interface HelloItf extends Remote {    String sayHello() throws RemoteException; } 

Lưu chương trình này vào tập tin HelloItf.java

Bước 02: Tạo lớp cài đặt (implement) cho giao diện đã được khai báo:

  • Cú pháp tổng quát:

import java.rmi. server.UnicastRemoteObject;import java.rmi.RemoteException;public class RemoteClass extends UnicastRemoteObject implements       InterfaceName {    public RemoteClass() throws RemoteException {         super();         ....... // Implement of Method    }    public ReturnType remoteMethodOne() throws RemoteException {         ....... // Implement of Method    }    public ReturnType remoteMethodTwo() throws RemoteException {         ....... // Definition of Method    }}

  • Định nghĩa lớp cài đặt có tên là Hello cài đặt cho remote interface HelloItf

import java.rmi. server.UnicastRemoteObject;import java.rmi.RemoteException;public class Hello extends UnicastRemoteObject implements HelloItf {     public Hello() throws RemoteException {         super();    }    public String sayHello() {         return "Hello World !";    }} 

Lưu chương trình này vào tập tin Hello.java

Bước 03: Viết chương trình Server:

  • Cú pháp tổng quát:

import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; public class ServerName {     public static void main(String args[]) {        if (System.getSecurityManager() == null) { // Cài đặt cơ chế bảo mật            System.setSecurityManager(new RMISecurityManager());         }         try {              // Tạo các đối tượng từ xa            RemoteClass remoteObject = new RemoteClass();             // Đăng ký tên cho các đối tượng từ xa            Naming.rebind(“RegistryName", remoteObject);             ...        }        catch (Exception e) {            System.out.println(”Error: . . .” + e);         }     } } 

  • Tạo server có tên HelloServer chứa một đối tượng từ xa  obj thuộc lớp cài đặt Hello. Đăng ký tên cho đối tượng obj là HelloObject

import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; public class HelloServer {     public static void main(String args[]) {        if (System.getSecurityManager() == null) {            System.setSecurityManager(new RMISecurityManager());         }         try {             Hello obj = new Hello();                 Naming.rebind("HelloObject", obj);                 System.out.println("HelloObject is registried");         }        catch (Exception e) {            System.out.println("Error: " + e);         }     } }

Lưu chương trình này vào tập tin HelloServer.java

Bước 04: Viết chương trình Client:

  • Cú pháp tổng quát:

import java.rmi.Naming;import java.rmi.RemoteException;public class Client {     public static void main(String args[]) {        String remoteObjectURL = "rmi://NameServer/RegistryName”;         Interfacename object = null;        try {            object = (InterfaceName)Naming.lookup(remoteObjectURL);             object.remoteMethodOne();        ...        }         catch (Exception e) {             System.out.println(" Error: ”+ e);         }     } }

  • Tạo client có tên là HelloClient, tìm đối tượng HelloObject trên rmiregistry chẳng hạn tại địa chỉ 172.18.211.160. Gọi phương thức sayHello() và in kết quả trả về ra màn hình.

import java.rmi.Naming;import java.rmi.RemoteException;public class HelloClient {     public static void main(String args[]) {        String helloURL = "rmi://172.18.211.160/HelloObject";        HelloItf object = null;        try {            object = (HelloItf)Naming.lookup( helloURL);             String message = object.sayHello();             System.out.println(message);        }         catch (Exception e) {            System.out.println("Client Error :" + e);         }     } }

Lưu chương trình vào tập tin HelloClient.java

Bước 05: Dịch các tập tin nguồn theo dạng RMI để tạo ra các lớp tương ứng và stub cho client, skeleton cho server: 

  • Cú pháp tổng quát:

javac InterfaceName.java RemoteClass.java Server.java Client.java( Tạo ra các lớp InterfaceName.class RemoteClass.class Server.class Client.class)

rmic RemoteClass( Tạo ra các lớp cho Skeleton và Stub: RemoteClass_Skel.class RemoteClass_Stub.class)

  • Biên dịch các lớp trong Hello:

javac Hello.java HelloItf.java HelloServer.java HelloClient.java

Kết quả biên dịch chương trình HelloClient.javarmic Hello.class

Biên dịch chương trình Hello.Java

Bước 06: Khởi động dịch vụ rmiregistry

  • Cú pháp tổng quát:

start rmiregistry [port]

Cổng mặc định là 1099.

  • Khới động dịch vụ rmiregistry trên cổng mặc định như sau:

 Khới động dịch vụ rmiregistry trên cổng mặc định

Khới động dịch vụ rmiregistry

Khi đó rmiregistry server sẽ chạy trên một cửa sổ mới, giữ nguyên cửa sổ này, không đóng nó lại.

rmiregistry server chạy trên một cửa sổ mới

Dịch vụ rmiregistry

Bước 07: Thực hiện chương trình Server

  • Cú pháp tổng quát:

java -Djava.security.policy =UrlOfPolicyFile   ServerName

Trong đó UrlOfPolicyFile là địa chỉ theo dạng URL của tập tin mô tả chính sách về bảo mật mã nguồn của Server (policy file). Nó qui định "ai" (chương trình, máy tính, quá trình trên) sẽ có quyền download các tập tin của nó trong đó có stub. Để đơn giản trong phần này ta cho phép tất cả mọi người đều có quyền download các tập tin của Server. Khi triển khai các ứng dụng thật sự ta phải có các chính sách bảo mật nghiêm ngặt hơn (Tham khảo tài liệu về Security của Java). File policy có dạng như sau:

grant {// Allow everything for nowpermission java.security.AllPermission;};

Lưu nội dung trên vào tập tin có tên policy.java

  • Thực thi HelloServer với địa chỉ tập tin plolicyThực thi HelloServer với địa chỉ tập tin plolicy nằm ở thư mục D:progspolicy.java

Bước 08: Thực thi chương trình Client:

  • Cú pháp tổng quát

java ClientName

  • Thực thi HelloClient với địa chỉ của rmiregistry đưa vào trong tham số

Kết quả biên dịch chương trình HelloClientĐể thực thi được chương trình HelloClient cần có hai class nằm cùng thư mục với nó là HelloItf.class và Hello_Stub.class.

0