"Xin chào! Và một chủ đề thú vị nữa: RMI. RMIviết tắt của Gọi phương thức từ xa . Nói cách khác, RMI là một cơ chế cho phép một đối tượng từ một máy Java gọi các phương thức trên các đối tượng từ một máy Java khác , ngay cả khi chúng ở trên các máy khác máy tính, ở các quốc gia khác nhau, hoặc ở các phía khác nhau của thế giới."

RMI - 1

"Ồ! Nghe thật tuyệt."

"Vâng. Nhưng tôi sẽ chỉ cố gắng cung cấp cho bạn một cái nhìn tổng quan. Với điều này, nếu bạn tìm hiểu quá sâu, bạn có thể bị nhầm lẫn bởi các sắc thái về cách thức hoạt động của nó."

"Nhưng nếu bạn không đi đến cực đoan, thì RMI không chỉ rất đơn giản mà còn đơn giản hóa rất nhiều cuộc sống của một lập trình viên. Vì điều đó, chúng tôi dành cho nó sự tôn trọng sâu sắc nhất."

"Vì vậy, chúng tôi muốn một đối tượng trong chương trình Java gọi một phương thức trên một đối tượng trong chương trình Java khác. Bất kể các chương trình này đang chạy ở đâu."

"Hãy xem xét ví dụ đơn giản nhất: khi cả hai chương trình đang chạy trên cùng một máy tính.  Để cho phép các chương trình tương tác qua Internet, bạn cần định cấu hình quyền của JVM , nhưng hôm nay chúng ta sẽ không đề cập đến vấn đề đó."

"Trong Java, bạn chỉ có thể gọi từ xa các phương thức của giao diện, không phải các lớp."

"Vì vậy, chúng ta có hai chương trình. Làm thế nào chúng có thể gọi các phương thức của nhau?"

"Hãy xem xét tình huống trong đó một chương trình chứa một đối tượng và chương trình thứ hai muốn gọi các phương thức trên đối tượng đó. Hãy gọi chương trình đầu tiên là máy chủ và chương trình thứ hai — máy khách. "

"Đầu tiên, tôi sẽ cung cấp một số mã mẫu, sau đó chúng ta sẽ phân tích nó."

"Vậy chương trình của chúng ta sẽ làm gì?"

"Hmm. Chà, để đơn giản, chương trình sẽ có một phương thức đảo ngược một chuỗi được truyền cho nó."

"Đủ đơn giản."

"Tốt, vậy chúng ta bắt đầu đi: "

"Đầu tiên, chúng tôi cần một giao diện đáp ứng yêu cầu của chúng tôi:"

Giao diện giao tiếp giữa các chương trình
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"Tôi đã tạo một giao diện Reverse và thêm giao diện đánh dấu từ xa vào nó, cũng như một RemoteException. Có thể xảy ra lỗi không mong muốn khi phương thức này được gọi. Nếu có, thì ngoại lệ này sẽ bị ném."

"Bây giờ chúng ta cần viết một lớp máy chủ thực hiện giao diện này:"

Lớp cho máy chủ
class ReverseImpl implements Reverse
{
 public String reverse(String str) throws RemoteException
 {
  return new StringBuffer(str).reverse().toString();
 }
}

"Tôi hiểu. Chúng tôi đảo ngược chuỗi trong phương pháp này."

"Chuẩn rồi."

"Bây giờ chúng ta cần làm cho đối tượng này có thể gọi được từ một chương trình khác. Đây là cách bạn thực hiện điều đó:"

chia sẻ đối tượng
public static final String UNIC_BINDING_NAME = "server.reverse";

public static void main(String[] args) throws Exception
{
 // Create an object to be accessible remotely.
 final ReverseImpl service = new ReverseImpl();

 // Create a registry of shared objects.
 final Registry registry = LocateRegistry.createRegistry(2099);
 // Create a stub for receiving remote calls.
 Remote stub = UnicastRemoteObject.exportObject(service, 0);
 // Register the stub in the registry.
 registry.bind(UNIC_BINDING_NAME, stub);

 // Put the main thread to sleep, or else the program will exit.
 Thread.sleep(Integer.MAX_VALUE);
}

"Tôi sẽ giải thích từng dòng một."

" Trong dòng 1 , chúng tôi lưu trữ một tên duy nhất (mà chúng tôi đã tạo) cho đối tượng từ xa của mình (đối tượng có thể truy cập từ xa) trong biến UNIC_BINDING_NAMENếu chương trình cho phép nhiều đối tượng có thể truy cập được, thì mỗi đối tượng phải có tên duy nhất của riêng mình. tên duy nhất của đối tượng là 'server.reverse'."

" Ở dòng 6 , chúng tôi tạo một đối tượng ReverseImpl có thể truy cập từ xa. Các phương thức của nó sẽ được gọi."

" Ở dòng 9, chúng ta tạo một đối tượng đặc biệt được gọi là sổ đăng ký. Chúng ta cần sử dụng nó để đăng ký các đối tượng mà chúng ta chia sẻ. JVM sẽ tương tác với chúng sau. 2099 là một cổng (một số duy nhất mà một chương trình khác có thể sử dụng để truy cập vào đăng ký đối tượng)."

"Nói cách khác, để truy cập một đối tượng, bạn cần biết số duy nhất của cơ quan đăng ký đối tượng (cổng) và tên duy nhất của đối tượng, đồng thời có giao diện giống như giao diện được triển khai bởi đối tượng từ xa."

"Tôi hiểu rồi. Đại loại như: gọi điện thoại (cần số) và hỏi Bill (tên của một đối tượng)?"

"Vâng. Bây giờ, chúng ta hãy tiếp tục."

" Ở dòng 11  , chúng ta tạo một sơ khai. Sơ khai là một đối tượng đặc biệt nhận thông tin về lệnh gọi từ xa, giải nén nó, giải tuần tự hóa các đối số của phương thức và gọi phương thức được yêu cầu. Sau đó, nó tuần tự hóa kết quả hoặc ngoại lệ, nếu có. và gửi lại tất cả cho người gọi."

"Tôi hiểu. Gần như. Bạn đã nói rằng nó 'giải tuần tự hóa các đối số của phương thức'. Vậy, điều đó có nghĩa là các đối số của các phương thức từ xa phải được tuần tự hóa?"

"Vâng. Bạn sẽ gửi chúng qua mạng bằng cách nào khác? Đúng, có những trường hợp ngoại lệ, tức là các đối tượng được truyền qua tham chiếu, nhưng hôm nay chúng ta sẽ không nói về chúng."

"Chúng tôi sẽ nói như thế này: bạn không thể chuyển các đối tượng không thể đánh số thứ tự, nhưng nếu bạn thực sự muốn, thì bạn có thể. Nhưng đó là một điều khó khăn, bạn biết đấy."

"ĐƯỢC RỒI."

"Vậy chúng ta tiếp tục đi."

" Ở dòng 13 , chúng tôi đăng ký sơ khai của đối tượng dưới một tên duy nhất trong sổ đăng ký."

" Ở dòng 16 , chúng ta đặt luồng chính ở chế độ ngủ. Tất cả lệnh gọi từ xa được xử lý trên các luồng riêng biệt. Điều quan trọng là chương trình đang chạy. Vì vậy, chúng ta chỉ cần đặt luồng chính ở chế độ ngủ ở đây. Thế là xong."

"ĐƯỢC RỒI."

"Tuyệt, sau đây là một ví dụ về khách hàng:"

Làm việc với một đối tượng từ xa
public static final String UNIC_BINDING_NAME = "server.reverse";

public static void main(String[] args) throws Exception
{
 // Create a registry of shared objects
 final Registry registry = LocateRegistry.createRegistry(2099);

 // Get the object (actually, this is a proxy object)
 Reverse service = (Reverse) registry.lookup(UNIC_BINDING_NAME);

 // Call the remote method
 String result = service.reverse("Home sweet home.");
}

"Tôi sẽ giải thích từng dòng mã này:"

" Dòng 1 là tên duy nhất  của đối tượng từ xa . Tên này phải giống nhau trên cả máy khách và máy chủ."

" Ở dòng 6  , chúng ta tạo một « sổ đăng ký đối tượng từ xa ». Cổng của nó (2099) phải giống với cổng của sổ đăng ký cho ứng dụng máy chủ."

" Ở dòng 9 , chúng tôi lấy đối tượng từ sổ đăng ký. Đối tượng được trả về là đối tượng proxy và được chuyển đổi thành giao diện. Giao diện phải kế thừa giao diện đánh dấu từ xa."

" Ở dòng 12 , chúng tôi gọi các phương thức của giao diện như thể đối tượng được tạo trong cùng một chương trình. Không có gì khác biệt."

"Tuyệt! Bây giờ tôi có thể viết các ứng dụng phân tán. Hoặc các trò chơi như Battleship cho Android."

"Bạn không dám, Amigo! Hệ điều hành Android đã bị cấm vào thế kỷ 27 sau nỗ lực chiếm lĩnh thế giới lần thứ ba. Robot không có quyền truy cập vào nó. Sẽ không có cách nào để kéo bạn ra khỏi nó . Bạn sẽ bắt đầu chạy xung quanh la hét, «Giết hết lũ người đi!»"

"Hmm. OK. Nhưng tôi vẫn phải hỏi Diego. Bạn không bao giờ biết được, có thể anh ấy sẽ có điều gì đó thú vị để nói về nó."

"Vậy thì đi hỏi anh ta đi. Được rồi, để đến ngày mai."

"Tạm biệt, Rishi. Cảm ơn vì bài học thú vị."