关于javarmi注册中心以及如何使用它的所有内容

javarmi代表远程方法调用,是调用在另一台计算机上运行的对象的方法的协议。了解有关javarmi注册表的所有信息以及如何使用它。...

RMI代表远程方法调用,顾名思义,它是Java程序调用另一台计算机上运行的对象的方法的协议。它提供了一个API(应用程序编程接口),用于从一个程序(称为服务器)导出一个对象,并从另一个程序(称为客户机)调用该对象的方法,可能运行在不同的计算机上。

java-rmi-registry

javarmi注册表是javarmi系统的一个关键组件,它为服务器注册服务和客户机查找这些服务提供了一个集中的目录。在本文中,我们将学习如何实现一个服务器来公开对象,以及如何实现一个客户端来调用服务器上的方法,以及如何在RMI注册表中注册和查找服务。

how java rmi registry works

声明服务器接口

为了了解javarmi系统如何工作的复杂性,让我们实现一个简单的服务器对象,提供一个接受名称并返回问候语的方法。以下是对象接口的定义:

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Greeting extends Remote
{
public String greet(String name) throws RemoteException;
}

接口的名称称为问候语。它提供了一个名为greet()的方法,它接受一个名称并返回一个合适的问候语。

要将此接口标记为可导出,它需要扩展java.rmi.Remote文件接口。该方法还需要声明一个throws子句列表java.rmi.RemoteException异常除了任何特定于应用程序的例外。这使得客户机代码可以处理(或传播)远程方法调用错误,例如找不到主机、连接失败等。

实现服务器对象

声明接口(客户端使用)后,我们实现服务器端对象,并提供greet()方法,如图所示。它使用一个简单的格式字符串来格式化问候语。

public class GreetingObject implements Greeting
{
private String fmtString = "Hello, %s";
public String greet(String name)
{
return String.format(this.fmtString, name);
}
}

服务器主方法

现在让我们将所有这些部分整理在一起,并实现服务器的main()方法。让我们来看看每一个相关的步骤。

  • The first step is to create the server object implementation.
    Greeting greeting = new GreetingObject();
  • Next, we obtain a stub for the server object from the RMI runtime. The stub implements the same interface as the server object. However the method implements the required communication with the remote server object. This stub is used by the client to transparently invoke the method on the server object.
    Greeting stub = (Greeting)UnicastRemoteObject.exportObject(greeting, 0);
  • Once the stub is obtained, we hand this stub over to the RMI registry to bind to a specified named service. When the client requests an implementation of this service, it receives the stub which knows how to communicate with the server object.In the following, the static method LocateRegistry.getRegistry() is used to obtain the local registry reference. The rebind() method is then used to bind the name to the stub.
    String name = "Greeting";
    Registry registry = LocateRegistry.getRegistry(port);
    registry.rebind(name, stub);

完整的主方法。

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class Main
{
static public void main(String[] args) throws Exception
{
if ( args.length == 0 ) {
System.err.println("usage: java Main port#");
System.exit(1);
}
int index = 0;
int port = Integer.parseInt(args[index++]);
String name = "Greeting";
Greeting greeting = new GreetingObject();
Greeting stub = (Greeting)UnicastRemoteObject.exportObject(greeting, 0);
Registry registry = LocateRegistry.getRegistry(port);
registry.rebind(name, stub);
System.out.println("Greeting bound to \"" + name + "\"");
}
}

构建服务器

现在让我们看看如何构建服务器。为了简单起见,我们在Linux上使用命令行构建,而不是使用Maven之类的构建工具。

下面将源文件编译为目标目录中的类文件。

rm -rf target
mkdir target
javac -d target src/server/*.java

将类文件收集到JAR文件中执行。

jar cvf target/rmi-server.jar -C target server

我们还收集将客户机编译为库JAR所需的接口文件。

jar cvf target/rmi-lib.jar -C target server/Greeting.class

实现客户机

现在让我们来看看如何实现用于调用服务器对象方法的客户机。

  • As with the server, obtain a reference to the registry, specifying the hostname where the registry is running, and the port number.
    Registry registry = LocateRegistry.getRegistry(host, port);
  • Next, lookup the service in the registry. The lookup() method returns a stub which can be used for invoking services.
    Greeting greeting = (Greeting) registry.lookup(name);
  • And invoke the method passing the required arguments. Here, we get the greeting by passing the name and printing it out.
    System.out.println(name + " reported: " + greeting.greet(myName));

完整的客户端代码:

package client;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import server.Greeting;
public class Client
{
static public void main(String[] args) throws Exception
{
if ( args.length != 3 ) {
System.err.println("usage: java Client host port myName");
System.exit(1);
}
int index = 0;
String host = args[index++];
int port = Integer.parseInt(args[index++]);
String myName = args[index++];
String name = "Greeting";
Registry registry = LocateRegistry.getRegistry(host, port);
Greeting greeting = (Greeting) registry.lookup(name);
System.out.println(name + " reported: " + greeting.greet(myName));
}
}

rmi注册表

现在让我们运行服务器程序,以便它可以开始服务请求。

java -cp target/rmi-server.jar server.Main 1099
# throws
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: xxx; nested exception is:
java.net.ConnectException: Connection refused

这个例外是什么?连接被拒绝。

出现此异常的原因是:请从服务器代码中注意,它试图连接到端口1099上的本地注册表。如果失败了,你会得到这个例外。

解决方案是运行RMI注册表。RMI注册表是Java虚拟机附带的一个程序,称为RMI注册表。它应该位于Java虚拟机安装的bin目录中。运行它非常简单:

/usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry

默认情况下,注册表侦听端口1099。要使其侦听另一个端口,请按如下所示指定端口号:

/usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 1100

使用netstat命令检查指定端口上是否确实存在侦听器:

netstat -an -t tcp -p | grep LISTEN
...
tcp6 0 0 :::1100 :::* LISTEN 23450/rmiregistry

运行服务器

现在让我们再次尝试运行服务器。

java -cp target/rmi-server.jar server.Main 1100
# throws
java.rmi.UnmarshalException: error unmarshalling arguments
...
Caused by: java.lang.ClassNotFoundException: server.Greeting
...

又是个例外!这次是什么?

服务器无法加载接口类服务器。问候语. 这是因为RMI注册表无法加载所需的类。所以需要指定所需类的位置。一种方法是指定CLASSPATH环境变量:

CLASSPATH=../../junk/target/rmi-lib.jar /usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 1100

尝试再次运行服务器时,给出了以下内容:

java -cp target/rmi-server.jar server.Main 1100
# prints
Greeting bound to "Greeting"

现在服务器正在运行。

运行客户端

在所有的部分都被组装和执行之后,运行客户机就很简单了。它需要合适的罐子来执行。其中包括包含main()方法的类和接口类。它接受指示RMI注册表运行位置的参数和问候语的名称。

java -cp target/rmi-client.jar:target/rmi-lib.jar client.Client localhost 1100 Peter
# prints
Greeting reported: Hello, Peter

总结

javarmi提供了一个API和工具来简化远程代码的执行。您可以实现一个向javarmi注册表注册服务对象的服务器。客户机可以查询注册表并获取服务对象存根以调用服务方法。正如这个例子所说明的,这一切都非常简单。

您在项目中使用javarmi吗?你有什么经历?你有没有别的选择?请在下面的评论中告诉我们。

  • 发表于 2021-03-12 15:58
  • 阅读 ( 303 )
  • 分类:编程

你可能感兴趣的文章

如何在Windows10中更改文本大小和字体

...如果所有这些都让你有了定制的心情,那么就来看看我们关于如何改变桌面的外观和感觉的技巧吧。完成后,您的系统将感觉全新。 ...

  • 发布于 2021-03-14 03:32
  • 阅读 ( 227 )

你需要看看这8个小众社交网络

...在在哪里)是一个旅行者的社交网络。无论你是想要一些关于廉价酒店的建议,需要了解外国城市的交通系统,还是只想在度假时找个人一起去喝一杯,韦恩都能帮上忙。 ...

  • 发布于 2021-03-15 04:14
  • 阅读 ( 147 )

如何创建一个人人都喜欢的亚马逊婴儿注册中心

...s,然后弹出Aboutyou部分来验证您的基本信息。然后,去“关于你的宝宝”部分。 ...

  • 发布于 2021-03-15 05:47
  • 阅读 ( 209 )

如何从你的邮箱里读一点,学到很多

...程时事通讯、发送到您收件箱的微型学习课程,以及10个关于各种主题的精彩时事通讯,所有这些都是非常好的建议,所以一定要查看它们! ...

  • 发布于 2021-03-17 15:05
  • 阅读 ( 259 )

在国外时如何解除电视直播

... 如何注册cyberghost ...

  • 发布于 2021-03-21 08:30
  • 阅读 ( 220 )

你需要知道的关于防弹托管服务的一切

...首席工程师Dhia Mahjoub在USENIX Enigma 2017的演讲中解释了更多关于流程的内容: ...

  • 发布于 2021-03-25 22:41
  • 阅读 ( 415 )

7个最好的语法和标点符号网站

...。不管你是新手还是母语人士,这都会让人困惑,尤其是关于正确用法的复杂规则。谢天谢地,这里有一些优秀的语法和标点符号网站,可以解释你需要知道的一切。 ...

  • 发布于 2021-03-29 08:55
  • 阅读 ( 214 )

如何合法地使用谷歌搜索任何书籍

...你可以进一步定制你的搜索结果。另外,如果你需要更多关于搜索内容的想法,你可以参考这些免费的网站来找到下一本书。 ...

  • 发布于 2021-03-30 17:25
  • 阅读 ( 272 )

如何在windows的控制面板中隐藏项目

...来进行一些额外的设置。您可以在我们的指南中阅读所有关于将本地组策略调整应用于特定用户的内容。 您还应该意识到组策略是一个非常强大的工具,因此值得花一些时间来了解它的功能。另外,如果你在公司网络上,帮每...

  • 发布于 2021-04-08 21:48
  • 阅读 ( 126 )

如何隐藏Windows10操作中心中的快速操作按钮

...果你不使用快速操作按钮,你可以很容易地隐藏他们使用注册表黑客。 相关:如何使用和自定义Windows 10操作中心 如何通过编辑注册表删除快速操作按钮 您可以自定义快速操作按钮上可用的操作,也可以隐藏整个操作中心。但...

  • 发布于 2021-04-09 15:27
  • 阅读 ( 133 )
kong1792561
kong1792561

0 篇文章