DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

RMI运行实例


计算机的远程通信有很多种方法, RPC 的设计目标是让一台主机(客户端)上的程序能够引用另一台主机(服务端)上对象,并运行它的方法,也就是“跨地址空间的进程间通信”, RMI 是RPC的Java语言实现。

本实例包含5个文件:

// ================= Hello.java ====================

package test.rmi;

import java.rmi.Remote;

import java.rmi.RemoteException;

/**

  • 远程方法调用接口,定义远程调用方法

*/

public interface Hello extends Remote {

String sayHello() throws RemoteException;

}

//================= HelloServer.java ============================= package test.rmi; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; /

服务器端,实现了Hello接口中的方法,用于实现远程调用方法的具体业务逻辑

/ public class HelloServer extends UnicastRemoteObject implements Hello { private static final long serialVersionUID = 1L; String name; public HelloServer(String s) throws RemoteException { super(); name = s; } public String sayHello() throws RemoteException { return "Hello from lc!"; } public static void main(String[] args) { /下面这句话若要加上,则需要进行权限的认证,即增加.policy文件 * 并且在命令行中使用如下格式 * java -Djava.security.policy=java.policy test.rmi.HelloServer / / System.setSecurityManager(new RMISecurityManager()); / Registry registry = null; try { /启动注册服务器,使用了这个语句就不再需要在命令行环境中 启动registry服务了 / registry = LocateRegistry.getRegistry(); / 若没有获得连接,则此句会抛出异常,后面在捕获后进行相关处理 */ registry.list(); System.out.println("Register the exist server!"); //\(NON-NLS-1\) } catch (RemoteException re) { try { int port = Integer.parseInt(Configur .getString("HelloServer.RegistryServerPort")); //\(NON-NLS-1\) registry = LocateRegistry.createRegistry(port); System.out.println("Create Registry Server!"); //\(NON-NLS-1\) } catch (Exception e) { e.printStackTrace(); } } try { HelloServer helloServer = new HelloServer("Hello"); registry.rebind( Configur.getString("HelloServer.HelloServerName"), helloServer); //\(NON-NLS-1\) System.out.println("HelloServer server start!"); //\(NON-NLS-1\) } catch (Exception e) { e.printStackTrace(); } } }

//================== HelloClient.java ============================ package test.rmi; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; / *

客户端,需要注册服务器并使用jndi

*/ public class HelloClient { public static void main(String[] args) { /下面这句话若要加上,则需要进行权限的认证,即增加.policy文件 * 并且在命令行中使用如下格式 * java -Djava.security.policy=java.policy test.rmi.HelloServer / / System.setSecurityManager(new RMISecurityManager()); / try { / 注册服务器 */ String hostName = Configur .getString("HelloServer.RegistryServerName"); int port = Integer.parseInt(Configur .getString("HelloServer.RegistryServerPort")); Registry registry = LocateRegistry.getRegistry(hostName, port); Hello hello = (Hello) registry.lookup(Configur .getString("HelloServer.HelloServerName")); String message = hello.sayHello(); System.out.println(message); } catch (Exception e) { e.printStackTrace(); } } }

//================= Configur.java ============================= package test.rmi; import java.util.MissingResourceException; import java.util.ResourceBundle; /* *

获取系统运行所需要的配置信息,对应的配置文件名称为config.properties

/ public class Configur { private static final String BUNDLE_NAME = "test.rmi.config"; private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle .getBundle(BUNDLE_NAME); private Configur() { }

/* *

通过key名称获得配置文件的相关信息

* @param key key名称 * @return String 配置文件信息 / public static String getString(String key) { try { return RESOURCE_BUNDLE.getString(key); } catch (MissingResourceException e) { return '!' + key + '!'; } } }

//================= config.properties ============================= HelloServer.RegistryServerPort=1111 HelloServer.HelloServerName=HelloServer HelloServer.RegistryServerName=10.31.1.71

源代码目录是e:\MyDoc\JEx\Ex1\src,Eclipse自动生成的class文件在e:\MyDoc\JEx\Ex1\bin(以及包目录)下。 运行方法:

  1. E:\MyDoc\JEx\Ex1\bin> rmic test.rmi.HelloServer (rmic.exe是$JAVA_HOME/bin里的文件)

生成e:\MyDoc\JEx\Ex1\bin\test\rmi\HelloServer_Stub.class文件(没有生成skeleton文件)

  1. E:\MyDoc\JEx\Ex1\bin> java test.rmi.HelloServer

Create Registry Server! HelloServer server start!

  1. 关闭本机的Windows防火墙;

  2. copy HelloClient.class, HelloServer_Stub.class, Hello.class, Configur.class, config.properties到另一台机器,运行 java test.rmi.HelloClient ,返回"Hello from lc!"。

要运行Server只需要Hello.class, HelloServer.class, Configur.class, config.properties 4个文件,HelloServer_Stub.class只在客户端需要。

可以看到客户端新建了一个Hello类型的对象,然后调用了这个对象的方法sayHello,而这个对象和方法的定义在另一台主机上。

RMI是一种同步调用方式,也就是说代码运行到"String message = hello.sayHello()"是会阻塞(block),直到服务端返回sayHello的结果,与此相对, JMS 是异步发送消息,客户端发送完消息后不等待结果返回,运行后面的代码。



Published

Apr 25, 2012

Last Updated

Apr 25, 2012

Category

Tech

Tags

  • Java 106
  • jms 1
  • rmi 1
  • rpc 2
  • 同步 3
  • 异步 1

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor