首页 > 代码库 > java远程调用RMI

java远程调用RMI

1.RMI

RMI是个典型的为java定制的远程通信协议,我们都知道,在single vm中,我们可以通过直接调用java object instance来实现通信,那么在远程通信时,如果也能按照这种方式当然是最好了,这种远程通信的机制成为RPC(Remote Procedure Call),RMI正是朝着这个目标而诞生的。


来看下基于RMI的一次完整的远程通信过程的原理:


  • 1. 客户端发起请求,请求转交至RMI客户端的stub类;
  • 2. stub类将请求的接口、方法、参数等信息进行序列化;
  • 3. 基于socket将序列化后的流传输至服务器端;
  • 4. 服务器端接收到流后转发至相应的skelton类;
  • 5. skelton类将请求的信息反序列化后调用实际的处理类;
  • 6. 处理类处理完毕后将结果返回给skelton类;
  • 7. Skelton类将结果序列化,通过socket将流传送给客户端的stub;
  • 8. stub在接收到流后反序列化,将反序列化后的Java Object返回给调用者。

2.简单例子

技术分享

PersonService.java

package rmi.service;

import java.rmi.Remote;
import java.rmi.RemoteException;

//此为远程对象调用的接口,必须继承Remote类
public interface PersonService extends Remote {
	public String getPersonName(int id) throws RemoteException;
}

PersonServiceImpl.java

package rmi.serviceImpl;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import rmi.service.PersonService;

public class PersonServiceImpl extends UnicastRemoteObject implements PersonService {
	public PersonServiceImpl() throws RemoteException {
		super();
	}

	@Override
	public String getPersonName(int id) throws RemoteException {
		String returnName;
		if (0 == id) {
			returnName = "张三";
		} else if (1 == id) {
			returnName = "李四";
		} else if (2 == id) {
			returnName = "王五";
		} else {
			returnName = "不存在";
		}
		System.out.println("------------getPersonName(" + id + ")------------");
		return returnName;
	}

}

ReremoServer.java

package rmi.remote;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

import rmi.service.PersonService;
import rmi.serviceImpl.PersonServiceImpl;

public class ReremoServer {
	public static void main(String[] args) {
		try {
			PersonService personService = new PersonServiceImpl();
			// 注册通讯端口
			LocateRegistry.createRegistry(6600);
			// 注册通讯路径
			Naming.rebind("rmi://localhost:6600/PersonService", personService);
			System.out.println("------服务启动成功------");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

ReremoClient.java

package rmi.remote;

import java.rmi.Naming;

import rmi.service.PersonService;

public class ReremoClient {
	public static void main(String[] args) {
		try {
			// 调用远程对象,注意RMI路径与接口必须与服务器配置一致
			PersonService personService = (PersonService) Naming.lookup("rmi://localhost:6600/PersonService");
			for (int i = 0; i < 5; i++) {
				String name = personService.getPersonName(i);
				System.out.println("name:" + name);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

3.运行结果

技术分享

技术分享

4.如何生成stub文件

技术分享

java远程调用RMI