在Java中使用 RMI(远程方法调用)的计算器
RMI(远程方法调用)是一种 API,用于访问在另一个 JVM (服务器端)上运行的对象。它主要用于创建分布式系统,在Java Rome 中提供。 Stub和Skeleton是用于处理客户端和服务器之间通信的两个对象。下图显示了 RMI 的概述。
![](https://mangodoc.oss-cn-beijing.aliyuncs.com/geek8geeks/Calculator_Using_RMI(Remote_Method_Invocation)_in_Java_0.png)
RMI的工作
这里,
- 存根对象:客户端机器上的存根对象构建一个信息块并将此信息发送到服务器。
- 骨架对象:骨架对象将来自存根对象的请求传递给远程对象。 RMI 包含一个保存所有服务器对象的 rmiregistry。服务器将所有对象绑定到注册表,然后客户端从相应的注册表中获取对象,之后客户端使用获取的对象调用方法。
使用 RMI 创建计算器的步骤
第 1 步:创建远程接口
首先,我们将创建 4 个接口(加法、减法、乘法、除法)。这些接口对操作很有帮助。要创建远程接口,我们需要扩展远程接口,并且接口中的方法原型应该抛出RemoteException 。
AddI.java
// Creating a AddInterface interface
import java.rmi.Remote;
public interface AddInterface extends Remote {
// Declaring the method prototype
public int add(int x, int y) throws RemoteException;
}
SubI.java
// Creating a SubInterface interface
import java.rmi.Remote;
public interface SubInterface extends Remote {
// Declaring the method prototype
public int sub(int x, int y) throws RemoteException;
}
MulI.java
// Creating a MulInterface interface
import java.rmi.Remote;
public interface MulInterface extends Remote {
// Declaring the method prototype
public int mul(int x, int y) throws RemoteException;
}
DivI.java
// Creating a DivInterface interface
import java.rmi.Remote;
public interface DivInterface extends Remote {
// Declaring the method prototype
public int div(int x, int y) throws RemoteException;
}
Impl.java
// Java program to implement the AddInterface,
// subInterface, MulInterface, and DivInterface
import java.rmi.*;
import java.rmi.server.*;
public class Impl extends UnicastRemoteObject
implements AddInterface, SubInterface, MulInterface,
DivInterface {
// Default constructor to throw RemoteException
// from its parent constructor
public Impl() throws Exception { super(); }
// Implementation of the AddInterface,
// subInterface, MulInterface, and DivInterface
public int add(int x, int y) { return x + y; }
public int sub(int x, int y) { return x - y; }
public int mul(int x, int y) { return x * y; }
public int div(int x, int y) { return x / y; }
}
Server.java
// Program for server application
import java.rmi.*;
import java.rmi.registry.*;
public class Server {
public static void main(String[] args) throws Exception
{
// Create an object of the interface
// implementation class
Impl obj = new Impl();
// Binds the remote object by the name ADD
Naming.rebind("ADD", obj);
System.out.println("Server Started");
}
}
Client.java
// Program for client application
import java.rmi.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Scanner sc = new Scanner(System.in);
while (true) {
// User Menu
System.out.println(
"\n1.Addition\n2.Subtraction\n3.multiplication\n4.division\n5.Exit");
System.out.println("Enter the option:");
int opt = sc.nextInt();
if (opt == 5) {
break;
}
System.out.println(
"Enter the the first number:");
int a = sc.nextInt();
System.out.println("Enter the second number:");
int b = sc.nextInt();
int n;
switch (opt) {
case 1:
// lookup method to find reference of remote
// object
AddInterface obj
= (AddInterface)Naming.lookup("ADD");
n = obj.add(a, b);
System.out.println("Addition= " + n);
break;
case 2:
SubInterface obj1
= (SubInterface)Naming.lookup("ADD");
n = obj1.sub(a, b);
System.out.println("Subtraction= " + n);
break;
case 3:
MulInterface obj2
= (MulInterface)Naming.lookup("ADD");
n = obj2.mul(a, b);
System.out.println("Multiplication = " + n);
break;
case 4:
DivInterface obj3
= (DivInterface)Naming.lookup("ADD");
n = obj3.div(a, b);
System.out.println("Division = " + n);
break;
}
}
}
}
子Ⅰ。Java
// Creating a SubInterface interface
import java.rmi.Remote;
public interface SubInterface extends Remote {
// Declaring the method prototype
public int sub(int x, int y) throws RemoteException;
}
穆里。Java
// Creating a MulInterface interface
import java.rmi.Remote;
public interface MulInterface extends Remote {
// Declaring the method prototype
public int mul(int x, int y) throws RemoteException;
}
第一部分。Java
// Creating a DivInterface interface
import java.rmi.Remote;
public interface DivInterface extends Remote {
// Declaring the method prototype
public int div(int x, int y) throws RemoteException;
}
第二步:远程接口的实现
现在是时候为所有接口提供实现了。要实现远程接口,该类应扩展为Java.rmi 包的UnicastRemoteObject类。此外,需要创建一个默认构造函数以Java类中的父构造函数中抛出 java .rmi.RemoteException。
实施。Java
// Java program to implement the AddInterface,
// subInterface, MulInterface, and DivInterface
import java.rmi.*;
import java.rmi.server.*;
public class Impl extends UnicastRemoteObject
implements AddInterface, SubInterface, MulInterface,
DivInterface {
// Default constructor to throw RemoteException
// from its parent constructor
public Impl() throws Exception { super(); }
// Implementation of the AddInterface,
// subInterface, MulInterface, and DivInterface
public int add(int x, int y) { return x + y; }
public int sub(int x, int y) { return x - y; }
public int mul(int x, int y) { return x * y; }
public int div(int x, int y) { return x / y; }
}
第三步:创建并执行服务器应用程序。
下一步是创建服务器应用程序并在单独的命令提示符下执行它。 Naming 类的 rebind 方法用于将远程对象绑定到新名称。
服务器。Java
// Program for server application
import java.rmi.*;
import java.rmi.registry.*;
public class Server {
public static void main(String[] args) throws Exception
{
// Create an object of the interface
// implementation class
Impl obj = new Impl();
// Binds the remote object by the name ADD
Naming.rebind("ADD", obj);
System.out.println("Server Started");
}
}
第四步:创建并执行客户端应用程序。
下一步是创建客户端应用程序并在单独的命令提示符下执行它。 Naming 类的查找方法用于获取 Stub 对象的引用。
客户。Java
// Program for client application
import java.rmi.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Scanner sc = new Scanner(System.in);
while (true) {
// User Menu
System.out.println(
"\n1.Addition\n2.Subtraction\n3.multiplication\n4.division\n5.Exit");
System.out.println("Enter the option:");
int opt = sc.nextInt();
if (opt == 5) {
break;
}
System.out.println(
"Enter the the first number:");
int a = sc.nextInt();
System.out.println("Enter the second number:");
int b = sc.nextInt();
int n;
switch (opt) {
case 1:
// lookup method to find reference of remote
// object
AddInterface obj
= (AddInterface)Naming.lookup("ADD");
n = obj.add(a, b);
System.out.println("Addition= " + n);
break;
case 2:
SubInterface obj1
= (SubInterface)Naming.lookup("ADD");
n = obj1.sub(a, b);
System.out.println("Subtraction= " + n);
break;
case 3:
MulInterface obj2
= (MulInterface)Naming.lookup("ADD");
n = obj2.mul(a, b);
System.out.println("Multiplication = " + n);
break;
case 4:
DivInterface obj3
= (DivInterface)Naming.lookup("ADD");
n = obj3.div(a, b);
System.out.println("Division = " + n);
break;
}
}
}
}
第五步:编译所有Java程序
现在我们需要编译所有的Java程序。要编译所有Java程序,我们需要打开命令提示符并进入相应的文件夹。现在进入存储所有文件的文件夹。我们可以使用以下命令一次编译所有文件;
javac *.java
第 6 步:创建存根和骨架
rmic 工具用于调用创建 Stub 和 Skeleton 对象的 rmi 编译器。它的原型是:
rmic classname
步骤:7 通过rmiregistry工具启动注册服务
现在使用 rmiregistry 工具启动 rmi 注册表服务。我们需要指定端口号。如果我们不指定端口号,它将使用默认端口号,例如我们使用端口号 5259。
rmiregistry 5259 or rmiregistry & or start rmiregistry(windows)
正确执行上述步骤后,它可能如下所示:
输出:成功执行上述步骤后,您可以看到以下输出或上述步骤中的任何混淆,您可以观看以下视频