Java 方法

Java中的远程方法调用

远程方法调用(RMI)是一种API,它允许对象调用另一个地址空间中存在的对象的方法,该对象可能在同一台机器上或远程机器上。通过RMI,运行在计算机(客户端)上的JVM中的对象可以调用另一个JVM(服务器端)中存在的对象的方法。RMI创建一个公共的远程服务器对象,通过服务器对象上的简单方法调用来启用客户端和服务器端的通信。

RMI的工作

客户端和服务器之间的通信是通过使用两个中间对象来处理的:Stub对象(在客户端)和Skeleton对象(在服务器端)。

存根(stub)对象

客户端计算机上的存根(stub)对象构建一个信息块并将此信息发送给服务器。该块由...组成

要使用的远程对象的标识符

要调用的方法名称

远程JVM的参数

Skeleton 对象

Skeleton 对象将来自存根对象的请求传递给远程对象。它执行以下任务

它调用服务器上存在的真实对象的所需方法。

它将从存根对象接收的参数转发给方法。

实现接口的步骤

定义一个远程接口

实现远程接口

使用rmic(rmi编译器)从实现类创建存根和Skeleton对象

开始rmiregistry

创建并执行服务器应用程序

创建并执行客户端应用程序。

第1步:定义远程接口
首先要做的是创建一个接口,该接口将提供远程客户端可以调用的方法的描述。这个接口应该扩展Remote接口,接口中的方法原型应该引发RemoteException。
// Creating a Search interface
import java.rmi.*;
public interface Search extends Remote
{
// Declaring the method prototype
public String query(String search) throws RemoteException;
}
第2步:实现远程接口
下一步是实现远程接口。为了实现远程接口,类应该扩展到java.rmi包的UnicastRemoteObject类。此外,还需要创建一个默认构造函数,以便在类中从其父构造函数中引发java.rmi.RemoteException。
// Java program to implement the Search interface
import java.rmi.*;
import java.rmi.server.*;
public class SearchQuery extends UnicastRemoteObject
implements Search
{
// Default constructor to throw RemoteException
// from its parent constructor
SearchQuery() throws RemoteException
{
super();
}
// Implementation of the query interface
public String query(String search)
throws RemoteException
{
String result;
if (search.equals("Reflection in Java"))
result = "Found";
else
result = "Not Found";
return result;
}
}
第3步:使用rmic从实现类创建Stub和Skeleton对象
rmic工具用于调用创建Stub和Skeleton对象的rmi编译器。它的原型是
rmic classname。对于上面的程序,需要在命令提示符
rmic SearchQuery中执行以下命令
第4步:启动rmiregistry
通过在命令提示符start rmiregistry处发出以下命令来启动注册表服务
第5步:创建并执行服务器应用程序
下一步是创建服务器应用程序并在单独的命令提示符下执行它。
服务器程序使用LocateRegistry类的createRegistry方法在服务器JVM中创建rmiregistry,并将端口号作为参数传递。
Naming类的rebind方法用于将远程对象绑定到新名称。
//program for server application
import java.rmi.*;
import java.rmi.registry.*;
public class SearchServer
{
public static void main(String args[])
{
try
{
// Create an object of the interface
// implementation class
Search obj = new SearchQuery();
// rmiregistry within the server JVM with
// port number 1900
LocateRegistry.createRegistry(1900);
// Binds the remote object by the name
// geeksforgeeks
Naming.rebind("rmi://localhost:1900"+
"/geeksforgeeks",obj);
}
catch(Exception ae)
{
System.out.println(ae);
}
}
}
第6步:创建并执行客户端应用程序
最后一步是创建客户端应用程序并在单独的命令提示符下执行。Naming类的查找方法用于获取Stub对象的引用。
//program for client application
import java.rmi.*;
public class ClientRequest
{
public static void main(String args[])
{
String answer,value="Reflection in Java";
try
{
// lookup method to find reference of remote object
Search access =
(Search)Naming.lookup("rmi://localhost:1900"+
"/geeksforgeeks");
answer = access.query(value);
System.out.println("Article on " + value +
" " + answer+" at GeeksforGeeks");
}
catch(Exception ae)
{
System.out.println(ae);
}
}
}

注意:上述客户端和服务器程序在同一台机器上执行,因此使用localhost。为了从另一台机器访问远程对象,localhost将被替换为远程对象所在的IP地址。

重要观点:

RMI是远程过程调用(RPC)的纯Java解决方案,用于在java中创建分布式应用程序。

stub和Skeleton 对象用于客户端和服务器端之间的通信。