RMI Example

26
http://thuvien-it.org/programming/rmi-remote-method- invocation-p1.html RMI – Remote Method Invocation (p1) Các chủ đề liên quan: [Java]Lập trình phân tán RMI (Phần 2) Các bước tạo ứng dụng với RMI Demo Đọc và Ghi File bằng Java nhập liệu từ bàn phím [Java]Lập trình Socket UDP (toàn tập) [Java]Tìm hiểu I/O Stream trong Java RMI là công nghệ xử lý (gọi hàm) từ xa thay cho việc truyền gởi dữ liệu theo kiểu cổ điển TCP, UDP. RMI hoạt động chủ yếu dựa trên cơ chế Skeleton/Stub tạo ra bộ khung sườn cho hoạt động gọi hàm . Như ta thấy : Ở client sẽ chứa interface của lớp xử lý , lớp interface để cho client sử dụng các hàm xử lý , tuy nhiên code xử lý chi tiết lại nằm ở phần implement ở server. Vì vậy client sử dụng các hàm ở locall nhưng phần xử lý thì là remote đây là 1 điểm mạnh của RMI (java) cũng như (Webservice) bên .NET. Việc gọi hàm đều thông qua Stub , ở server có nhiệm vụ đăng ký phần implement lên server (bind to name). Còn ở client thì sau khi khai báo 1 đối tượng interface thì lookup phần implement cho đối tượng này (lookup name). Thông qua lookup sẽ tạo nên 1 Stub, nhờ stub này việc gởi và nhận dữ liệu sẽ thành công.

Transcript of RMI Example

Page 1: RMI Example

http://thuvien-it.org/programming/rmi-remote-method-invocation-p1.html

RMI – Remote Method Invocation (p1)

    Các chủ đề liên quan:   

[Java]Lập trình phân tán RMI (Phần 2)

Các bước tạo ứng dụng với RMI

Demo Đọc và Ghi File bằng Java nhập liệu từ bàn phím

[Java]Lập trình Socket UDP (toàn tập)

[Java]Tìm hiểu I/O Stream trong Java

RMI là công nghệ xử lý (gọi hàm) từ xa thay cho việc truyền gởi dữ liệu theo kiểu cổ điển TCP, UDP.RMI hoạt động chủ yếu dựa trên cơ chế Skeleton/Stub tạo ra bộ khung sườn cho hoạt động gọi hàm .

Như ta thấy : Ở client sẽ chứa interface của lớp xử lý , lớp interface để cho client sử dụng các hàm xử lý , tuy nhiên code xử lý chi tiết lại nằm ở phần implement ở server. Vì vậy client sử dụng các hàm ở locall nhưng phần xử lý thì là remote đây là 1 điểm mạnh của RMI (java) cũng như (Webservice) bên .NET.

Việc gọi hàm đều thông qua Stub , ở server có nhiệm vụ đăng ký phần implement lên server (bind to name). Còn ở client thì sau khi khai báo 1 đối tượng interface thì lookup phần implement cho đối tượng này (lookup name). Thông qua lookup sẽ tạo nên 1 Stub, nhờ stub này việc gởi và nhận dữ liệu sẽ thành công.

Page 2: RMI Example

RMI là công nghệ xử lý (gọi hàm) từ xa thay cho việc truyền gởi dữ liệu theo kiểu cổ điển TCP, UDP.

RMI hoạt động chủ yếu dựa trên cơ chế Skeleton/Stub tạo ra bộ khung sườn cho hoạt động gọi hàm .

Như ta thấy : Ở client sẽ chứa interface của lớp xử lý , lớp interface để cho client sử dụng các hàm xử lý , tuy nhiên code xử lý chi tiết lại nằm ở phần implement ở server. Vì vậy client sử dụng các hàm ở locall nhưng phần xử lý thì là remote đây là 1 điểm mạnh của RMI (java) cũng như (Webservice) bên .NET.

Việc gọi hàm đều thông qua Stub , ở server có nhiệm vụ đăng ký phần implement lên server (bind to name). Còn ở client thì sau khi khai báo 1 đối tượng interface thì lookup phần implement cho đối tượng này (lookup name). Thông qua lookup sẽ tạo nên 1 Stub, nhờ stub này việc gởi và nhận dữ liệu sẽ thành công.

Phần 1 Cài Đặt:

InterfaceRMI.java

Code:

import java.rmi.Remote;import java.rmi.RemoteException;public interface InterfaceRMI extends Remote {public String strDelete(String s, int i,int n) throws RemoteException;}

ImplementRMI.java

Code:

import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;

public class ImplementRMI extends UnicastRemoteObject implements InterfaceRMI{

private static final long serialVersionUID = 1L;

public ImplementRMI() throws RemoteException{super();

}public String strDelete(String s,int i,int n){if(0<i && i<n && n< s.length())return s.substring(0,i-1) + s.substring(n+1);return "Chieu sai chuoi khong phu hop voi yeu cau";}}

Page 3: RMI Example

Client.java

Code:

import java.rmi.Naming;import java.rmi.NotBoundException;import java.util.Scanner;import java.io.*;public class Client {

public static void main(String[] args) throws NotBoundException, IOException {// TODO Auto-generated method stubInterfaceRMI strDelete = (InterfaceRMI)Naming.lookup("strDelete");Scanner scan = new Scanner(System.in);System.out.println("Nhap chuoi  :");String temp = scan.nextLine();System.out.print("Nhap vi tri bat dau cua chuoi con: ");int i = scan.nextInt();System.out.print("Nhap vi tri ket thuc cua chuoi con: ");int n = scan.nextInt();System.out.println("Chuoi sau khi xu ly :"+ strDelete.strDelete(temp, i, n));}}

InterfaceRMI strDelete = (InterfaceRMI)Naming.lookup(“strDelete”);//Lookup tìm phần implement đã d.c reg trên server

Server.java

Code:

import java.rmi.AlreadyBoundException;import java.rmi.RemoteException;import java.rmi.registry.LocateRegistry;import java.rmi.Naming;import java.net.MalformedURLException;public class Server {

/*** @param args* @throws RemoteException* @throws AlreadyBoundException* @throws MalformedURLException*/public static void main(String[] args) throws RemoteException, MalformedURLException, AlreadyBoundException {// TODO Auto-generated method stubLocateRegistry.createRegistry(1099);System.out.println("Server has started");Naming.bind("rmi://localhost/strDelete", new ImplementRMI());System.out.println("Server ready for use");}

Page 4: RMI Example

}

LocateRegistry.createRegistry(1099); //Tạo portNaming.bind(“rmi://localhost/strDelete”, new ImplementRMI()); //Reg phần implement

[Java]Lập trình phân tán RMI (Phần 2)

    Các chủ đề liên quan:   

RMI – Remote Method Invocation (p1) Các bước tạo ứng dụng với RMI [Java]Lập trình Socket UDP (toàn tập) Demo Đọc và Ghi File bằng Java nhập liệu từ bàn phím

[Java] Thành phần JCheckBox – Swing

Trong một ứng dụng không phân tán của java, đoạn mã trong một đối tượng có thể gọi phương thức của một đối tượng khác và máy ảo Java phân giải địa chỉ và truyền tham số từ đối tượng gọi đến phương thức được gọi, ngoài ra nó cũng trả về các giá trị cho đối tượng gọi thực thi phương thức

Trong ứng dụng phân tán lời triệu gọi các phương thức sẽ thông qua lớp trung gian. Lớp trung gian tồn tại cả trên Server và Client. Phía Client lớp trung gian gọi là stub (lớp móc). Phía Server lớp trung gian gọi là skeleton (lớp nối)

Stub sẽ gọi kiến trúc RMI bên phía máy khách và di chuyển dữ liệu qua mạng đến kiến trúc RMI trên máy chủ, đến lượt nó sẽ gọi thực thi một đối tượng bè bạn bên phía máy chủ gọi là skeleton.

Đối tượng skeleton sẽ gọi phương thức của đối tượng thật sự bên phía máy chủ. Đến khi trả lại kết quả thì một cơ chế giống hệt như trên sẽ được gọi thực thi nhưng theo thứ tự ngược lại, khi đó kết quả trả về sẽ được truyền cho đối tượng skeleton trên máy chủ, và được đối tượng này truyền theo đường mạng sử dụng kiến trúc RMI, tiếp đến nó sẽ gọi đối tượng stub bên phía máy khách, và trả về giá trị cho đối tượng gọi phương thức

Page 5: RMI Example

Ví dụ như hình trên

Đối tượng C1 được cài đặt trên máy C.Trình biên dịch rmic.exe của Java sẽ tạo ra C1_stub và C1_skel. Lớp C1_stub được mang về máy A.Khi A1 trên máy A triệu gọi phương thức của đối tượng C1 nó sẽ chuyển lời gọi phương thức cho lớp trung gian C1_stub.

Trong lập trình RMI là người lập trình chỉ cần lập trình các lời gọi phương thức vì đối tượng được gọi đã hiện diện trong máy ảo Java của nó

Tóm tắt quá trình xây dựng một ứng dụng RMI

1. Tạo giao diện kế thừa từ lớp Remote: extends Remote2. Triển khai giao diện bằng cách implements lớp đã tạo trong bước 13. Đăng ký đối tượng với rmiregistry4. Viết chương trình triệu gọi phương thức từ xa (Máy client)

Xây dựng các đối tượng bao gồm tạo và triển khai giao diện

Hầu như không có khác biệt giữa lập trình trên máy cục bộ và lập trình phân tán trong RMI.

Tất cả các lớp muốn có thể được triệu gọi từ xa thì phải có 2 phần: phần giao diện (interface) và phần cài đặt (implementation). Phần giao diện phải thừa kế từ một lớp của Java là lớp Remote. Phần cài đặt không những cài đặt phần giao diện mà còn phải thừa kế từ một lớp của Java là lớp UnicastRemoteObject

Page 6: RMI Example

Dưới đây là một giao diện (interface) đơn giản cho một lớp truyền vào và lấy ra một String:

Code:import java.rmi.*;public interface Example extends Remote {public void setString( String s ) throws RemoteException;public String getString() throws RemoteException;}

Và đây là phần cài đặt (implementation):Code:import java.rmi.*;import java.rmi.server.*;

public class ExampleServer extends UnicastRemoteObject implements Example {private String stringState;public ExampleServer() throws RemoteException{}public void setString( String s ) throws RemoteException{stringState = s;}

public String getString() throws RemoteException{return stringState;}}

Trình biên dịch rmic.exe sẽ giúp ta tạo hai lớp trung gian Stub và SkeVới ví dụ trên bạn cần dùng rmic.exe để dịch lớp ExampleServer

Vấn đề tham biến và tham trị trong kỹ thuật lập trình phân tán đối tượng RMI

Vấn đề tham biến và tham trị trong kỹ thuật lập trình phân tán đối tượng RMI.

Kế thừa từ lớp Remote: đối tượng được tham khảo theo tham biến (GET OBJECT BY REFERENCE)Ví dụ:RemoteClass: (interface & implement): đối tượng được gọi từ xaMyRemoteClass.java

Page 7: RMI Example

Code: (Click Here to Select All)

import java.rmi.*;

public interface MyRemoteClass extends Remote{

public int getMyAttribute() throws RemoteException;

public void setMyAttribute(int value) throws RemoteException;

}

MyRemoteClassImpl.javaCode: (Click Here to Select All)

import java.rmi.*;

public class MyRemoteClassImpl implements MyRemoteClass{

private int myAttribute=0;

public int getMyAttribute() throws RemoteException

{

return myAttribute;

}

public void setMyAttribute(int value) throws RemoteException

{

myAttribute=value;

}

}

ServerClass : đăng ký đối tượng RemoteClassMyRemoteClassServer.javaCode: (Click Here to Select All)

import java.rmi.server.*;

import java.rmi.*;

public class MyRemoteClassServer{

public static void main(String args[]){

try{

MyRemoteClassImpl c=new MyRemoteClassImpl();

Page 8: RMI Example

System.out.println("Exporting MyRemoteClass...");

UnicastRemoteObject.exportObject(c);

Naming.bind("rmi://localhost/MyRemoteClass",c);

System.out.println("Register MyRemoteClass!");

while (true){

System.out.println("Value of c " +c.getMyAttribute());

}

}catch(Exception e){

System.out.println(e);

}

}

}

ClientClass : sử dụng đối tượng RemoteClassMyRemoteClassClient.javaCode: (Click Here to Select All)

import java.rmi.*;

public class MyRemoteClassClient{

public static void main(String args[]){

try{

System.out.println("DEMO: GET OBJECT BY REFERENCE");

MyRemoteClass c=(MyRemoteClass)Naming.lookup("rmi://localhost/MyRemoteClass");

c.setMyAttribute(12);

System.out.println("Value of c: " +c.getMyAttribute());

MyRemoteClass c1=(MyRemoteClass)Naming.lookup("rmi://localhost/MyRemoteClass");

System.out.println("Value of c1: " + c1.getMyAttribute());

Page 9: RMI Example

c1.setMyAttribute(16);

System.out.println("Value of c after c1 set to 16: " +c.getMyAttribute());

}catch(Exception e){

System.out.println(e);

}

}

}

Hiện thực từ lớp Serializable: đối tượng được tham khảo theo tham trị

RemoteClass: (interface & implement): đối tượng được gọi từ xaMyRemoteClass.javaCode: (Click Here to Select All)

import java.rmi.*;

public interface MyRemoteClass extends Remote{

public MySerializableClass myFunction(MySerializableClass c) throws RemoteException;

}

MyRemoteClassImpl.javaCode: (Click Here to Select All)

import java.rmi.*;

public class MyRemoteClassImpl implements MyRemoteClass{

public MySerializableClass myFunction(MySerializableClass c) throws RemoteException

{

c.setMyAttribute(c.getMyAttribute()*2);//Change c

return c;

}

}

SerializableClass : đối tượng làm tham số gọi qua RemoteClassMySerializableClass.javaCode: (Click Here to Select All)

Page 10: RMI Example

import java.io.*;

public class MySerializableClass implements Serializable{

private int myAttribute=0;

public int getMyAttribute()

{

return myAttribute;

}

public void setMyAttribute(int value)

{

myAttribute=value;

}

}

ServerClass : đăng ký đối tượng RemoteClassMySerializableClassServer.javaCode: (Click Here to Select All)

import java.rmi.server.*;

import java.rmi.*;

public class MySerializableClassServer{

public static void main(String args[]){

try{

MyRemoteClassImpl c=new MyRemoteClassImpl();

System.out.println("Exporting MyRemoteClass...");

UnicastRemoteObject.exportObject(c);

Naming.bind("rmi://localhost/MyRemoteClass",c);

System.out.println("Register MyRemoteClass!");

}catch(Exception e){

Page 11: RMI Example

System.out.println(e);

}

}

}

ClientClass : sử dụng đối tượng RemoteClassMySerializableClassClient.javaCode: (Click Here to Select All)

import java.rmi.*;

public class MySerializableClassClient{

public static void main(String args[]){

try{

System.out.println("DEMO: GET OBJECT BY VALUE");

MyRemoteClass c=(MyRemoteClass)Naming.lookup("rmi://localhost/MyRemoteClass");

//

MySerializableClass myData=new MySerializableClass();

myData.setMyAttribute(16);

System.out.println("Data before call Remote Function: " + myData.getMyAttribute());

//

MySerializableClass myNewData=c.myFunction(myData);

//

System.out.println("Data after call Remote Function: " + myData.getMyAttribute());

System.out.println("Return Data from Remote Function: " + myNewData.getMyAttribute());

}catch(Exception e){

System.out.println(e);

}

}

Page 12: RMI Example

}

Lập trình mạng với Java - Lập trình phân tán đối tượng - RMI

Bài hướng dẫn này hướng dẫn các bạn kỹ thuật lập trình phân tán RMI.Click this bar to view the full image.

Nội dung: Giới thiệu gói thư viện Java.net Sử dụng TCP socket Sử dụng UDP socket RMI và kỹ thuật phân tán đối tượng

Giới thiệu gói thư viện Java.netMột số lớp cần thiết trong gói thư viện java.net:

InetAddress: quản lý địa chỉ Internet Socket: tạo kết nối từ client đến server ServerSocket: tạo kết nối từ phía server đến client DatagramSocket: gửi nhận dữ liệu dưới dạng gói tin DatagramPackage: gói tin chứa dữ liệu gửi nhận sử dụng cho lớp

DatagramSocket URL: địa chỉ định vị tài nguyên trên mạng

Lớp InetAddressSử dụng để quản lý địa chỉ host theo tên hay sốCác phương thức thường được sử dụng:

static InetAddress getLocalHost() : trả về đối tượng InetAddress là địa chỉ của máy cục bộ(localhost).

static InetAddress getByName(String hostName): trả về đối tượng InetAddress là địa chỉ của máy có tên là hostName.

Page 13: RMI Example

static InetAddress[] getAllByName(String hostName): trả về tất cả các đối tượng InetAddress là địa chỉ của máy có tên là hostName.

byte[] getAddress(): trả về địa chỉ IP của đối tượng InetAddress dưới dạng chuỗi byte.

string getHostAddress(): trả về địa chỉ IP của đối tượng InetAddress dưới dạng string.

Ví dụ:Code: (Click Here to Select All)

try{

//Lấy đối tượng InetAddress chứa thông tin về máy chủ

InetAddress host=

InetAddress.getByName(“www.khoinguonit.com”);

Sytem.out.println(“Host Name :”+host.getHostName());

Sytem.out.println(“IP Address:”+host.getHostAddress());

}

catch( UnknownHostException e){

System.out.println(“Address not found!”);

}

Lớp SocketSử dụng cho client kết nối đến serverCác hàm tạo

Socket(String hostName,int port): tạo đối tượng socket và kết nối đến server hostName ở số hiệu cổng port.

Socket(InetAddress address,int port): tạo đối tượng socket kết nối đến address và port.

Socket(String hostName, int port, boolean stream): tạo đối tượng socket kết nối đến hostName và port, stream=true nếu qui định kết nối theo TCP, stream=false nếu qui định kết nối theo UDP. Tuy nhiên nếu sử dụng socket theo UDP thì nên sử dụng lớp DatagramSocket.

Các phương thức thường được sử dụng: InputStream getInputStream() : lấy luồng nhập để có thể nhận dữ liệu từ máy ở

xa. OutputStream getOutputStream(): lấy luồng xuất để có thể gửi dữ liệu đến máy

ở xa. InetAddress getInetAddress(): trả về đối tượng InetAddress chứa địa chỉ của

máy đang kết nối đến.

Page 14: RMI Example

int getPort(): trả về số hiệu cổng sử dụng của máy đang kết nối. void close(): đóng socket, cắt kết nối.

Ví dụ:Code: (Click Here to Select All)

try{

//Kết nối đến máy chủ

Socket mySocket=new Socket(“www.hcmutrans.edu.vn”,8080);

//Luồng nhâp để nhận dữ liệu

DataInputStream inStream=new DataInputStream(mySocket.getInputStream());

//Luồng xuất để gửi dữ liệu

DataOutputStream outStream=new DataOutputStream(mySocket.getOutputStream());

//Bắt đầu gửi nhận dữ liệu qua inStream và outStream …

}

catch(Exception e){

System.out.println(e);

}

Lớp ServerSocketSử dụng cho server, tạo socket và lắng nghe kết nối trên một portHàm tạo và các phương thức:

ServerSocket(int port): tạo đối tượng socket và lắng nghe ở port. Socket accept(): dừng lại và đợi client kết nối đến, khi nhận được thông tin kết

nối sẽ trả về đối tượng Socket kết nối với client. void close(): cắt kết nối và đóng socket.

Ví dụ:Code: (Click Here to Select All)

try{

//Tạo serverSocket lắng nghe ở cổng 12345

ServerSocket server=new ServerSocket(12345);

//Chờ client kết nối đến

Socket client=server.accept();

Page 15: RMI Example

//Tạo InputStream và OutputStream qua socket client

// và bắt đầu gửi nhận dữ liệu…

}

catch(Exception e){

System.out.println(e);

}

Lớp DatagramSocketSử dụng giao thức UDP, truyền nhận dữ liệu dưới dạng gói tin.Hàm tạo và các phương thức:

DatagramSocket(): tạo đối tượng socket sử dụng giao thức UDP. DatagramSocket(int port): tạo đối tượng socket và kết nối đến số hiệu cổng

port. void send(DatagramPacket p): gửi gói tin p đi. void receive(DatagramPacket p): nhận gói tin p về. void close(): đóng socket.

Lớp DatagramPacketKhai báo gói tin gửi đi trên mạng qua kết nối DatagramSocket.Hàm tạo và các phương thức:

DatagramPacket(byte buffer[], int len): tạo gói tin có dữ liệu chứa trong buffer, chiều dài buffer là len.

DatagramPacket(byte buffer[], int len, InetAddress dest, int port): tạo gói tin gửi đến địa chỉ dest với số hiệu cổng port.

InetAddess getAddress(): lấy địa chỉ chứa trong gói tin. int getPort(): lấy số hiệu cổng chứa trong gói tin. byte[] getData(): lấy dữ liệu trong gói tin. int getLength(): lấy chiều dài gói dữ liệu.

Ví dụ:Code: (Click Here to Select All)

try{

//Tạo socket UDP kết nối với cổng 2345

DatagramSocket socket=new DatagramSocket(2345);

//Khai báo Buffer gửi nhận

byte outBuffer[];

byte inBuffer[]=new byte[256];

Page 16: RMI Example

//Khai báo Datagram Packet để gửi và nhận

DatagramPacket outDatagram;

DatagramPacket inDatagram=new DatagramPacket(inBuffer,inBuffer.length);

//Bắt đầu gửi nhận dữ liệu …

// nhận dữ liệu:

socket.receive(inDatagram); // … xử lý dữ liệu ở inBuffer

// chuẩn bị dữ liệu trong outDatagram

// gửi dữ liệu:

socket.send(outDatagram);

//……

}

catch(Exception e){

System.out.println(e);

}

Lớp URLURL(Uniform Resource Locator): sử dụng để định vị tài nguyên mạng.Hàm tạo và các phương thức:

URL(String s): tạo đối tượng URL từ địa chỉ s là một chuỗi. Object getContent(): lấy về nội dung từ địa chỉ URL có được. String getFile(): lấy về tên tập tin nằm trong chuỗi địa chỉ URL. String getHost(): lấy tên máy chủ. int getPort(): lấy số hiệu cổng. InputStream openStream(): mở luồng để đọc thông tin từ máy chủ.

Ví dụ:Code: (Click Here to Select All)

try{

//Tạo URL kết nối đến trang web

URL url=new URL(“http://www.hcmutrans.edu.vn/index.htm“);

//Tạo luồng nhập để đọc dữ liệu

BufferReader inStream=new BufferReader(new InputStreamReader(url.openStream()));

//In nội dung trang index.htm ra màn hình …

String s;

Page 17: RMI Example

while ((s=inStream.readLine())!=null){

System.out.println(s);

}

}

catch(Exception e){

System.out.println(e);

}

Sử dụng TCP socketServer: tạo một đối tượng ServerSocket lắng nghe đến một số hiệu cổng nào đó.Client: tạo một đối tượng Socket kết nối với server qua tên/địa chỉ IP và số hiệu cổng.

Sử dụng UDP socketServer: tạo một đối tượng DatagramSocket lắng nghe đến một số hiệu cổng nào đó.Client: tạo một đối tượng DatagramSocket và gửi dữ liệu đến server qua địa chỉ và cổng đã được biết trước. Server gửi trả dữ liệu qua địa chỉ và cổng của client chứa trong gói tin này.

RMI và kỹ thuật lập trình phân tán đối tượngKhái niệm lập trình phân tán đối tượngThiết kế ứng dụng phân tán RMIVấn đề truyền tham sốKết nối mạng và vấn đề tường lửa(firewall)SOAP

Khái niệm lập trình phân tán đối tượngCác đối tượng nằm phân tán trên các máy vật lý khác nhau.Đối tượng có thể triệu gọi phương thức của đối tượng nằm trên một máy khác – triệu gọi từ xa.RMI (Remote method Invoke): là cách thức giao tiếp của các đối tượng Java có mã lệnh cài đặt nằm trên các máy khác nhau có thể triệu gọi lẫn nhau

Click this bar to view the full image.

Page 18: RMI Example

Gọi phương thức từ xa và các vấn đề phát sinhCác đối tượng nằm trên các máy khác nhau, có không gian địa chỉ khác nhau nên việc tham chiếu biến hay địa chỉ là khác nhau.Ví dụ khi truyền tham số là con trỏ cho một phương thức gọi từ xa, ở máy này con trỏ tồn tại, nhưng ở máy ở xa, có thể chưa có vùng nhớ nào đã cấp phát dành cho con trỏ này.Lời gọi phương thức cục bộ luôn trả về kết quả, trong khi gọi phương thức từ xa thông qua kết nối mạng và có thể bị ngắt ngang do mạng có sự cố.

Lớp trung gian: Stub & SkeletonĐể giải quyết vấn đề trên, Java không cho phép gọi phương thức từ xa trực tiếp mà thông qua lớp trung gianLớp trung gian tồn tại ở cả máy gọi và máy được gọi.

Máy gọi cần lớp trung gian là Stub Máy được gọi cần lớp trung gian là Skeleton

Click this bar to view the full image.

Page 19: RMI Example

Xây dựng ứng dụng phân tán RMIVí dụ xây dựng ứng dụng CalculatorServer/Client

Calculator: lớp có phương thức sẽ được gọi từ xa. CalculatorClient: lớp sử dụng các phương thức của Calculator CalculatorServer: lớp sẽ đăng ký Calculator để có thể gọi từ xa

Click this bar to view the full image.

B1. Tạo interface CalculatorInterface Calculator cần kế thừa lớp Remote để có thể gọi được từ xaFile Calculator.java có nội dung như sauCode: (Click Here to Select All)

import java.rmi.*;

public interface Calculator extends Remote{

public int sum(int n);

// sum = 1+2+3+…+n

}

//Chỉ khai báo các phương thức và

//đối số, không có nội dung

Page 20: RMI Example

B2. Tạo lớp CalculatorImpl hiện thực interface CalculatorFile CalculatorImpl.java có nội dung:Code: (Click Here to Select All)

import java.rmi.*;

public class CalculatorImpl implements Calculator{

public int sum(int n){

int s=0;

for (int i=1;i<=n;i++)

s=s+i;

return s;

}

}

B3. Dịch thành các file class, tạo Stub & SkeletonCode: (Click Here to Select All)

C:\>javac Calculator.java

C:\>javac CalculatorImpl.java

C:\>rmic CalculatorImpl

Kết quả quá trình dịch được các file: Calculator.class CalculatorImpl.class CalculatorImpl_Stub.class CalculatorImpl_Skel.class

B4. Xây dựng CalculatorServer.java để cài đặt đối tượng CalculatorCode: (Click Here to Select All)

import java.rmi.server.*;

import java.rmi.*;

public class CalculatorServer{

public static void main(String args[]){

try{

CalculatorImpl c=new CalculatorImpl();

Page 21: RMI Example

System.out.println("Exporting Calculator...");

UnicastRemoteObject.exportObject(c);

Naming.bind("rmi://localhost/MyCalculator",c);

System.out.println("Register Calculator!");

}catch(Exception e){

System.out.println(e);

}

}

}

B5. Thực thi bộ đăng ký đối tượng rmiregistry.exeChức năng của bộ đăng ký là đón nhận các kết nối chứa thông tin về đối tượng do phương thức Naming.bind() gửi đến.Kích hoạt bộ đăng ký:C:\jsdk\bin\rmiregistry.exeKích hoạt CalculatorServer:java CalculatorServerB6. Xây dựng CalculatorClient.java sử dụng đối tượng CalculatorCode: (Click Here to Select All)

import java.rmi.*;

public class CalculatorClient{

public static void main(String args[]){

try{

System.out.println("Finding Object...");

Calculator c=(Calculator)Naming.lookup("rmi://localhost/MyCalculator");

//Test c

System.out.println("Sum(12)= " + c.sum(12));

}catch(Exception e){

System.out.println(e);

}

}

Page 22: RMI Example

}

Triển khai ứng dụngTrên Server cần các file sau:

Calculator.class CalculatorImpl.class CalculatorImpl_Skel.class CalculatorImpl_Stub.class CalculatorServer.class

Trên Client cần các file sau: Calculator.class CalculatorImpl_Stub.class CalculatorClient.class

Truyền tham số trong các lời gọi phương thức từ xaTham số: tham trị và tham biếnTham số trong RMI:

Các kiểu dữ liệu đơn giản như: int, char, float,… được truyền theo tham trị. Các đối tượng muốn truyền qua mạng phải cài đặt giao tiếp Remote hoặc

Serializable. Đối tượng cài đặt Remote sẽ truyền tham biến, cài đặt theo Serializable truyền theo tham trị