Java RMI基础
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。
Transport Layer:该层连接客户端和服务器。它管理现有连接并建立新连接。Stub:存根是客户端远程对象的表示(代理)。它驻留在客户端系统中;它充当客户端程序的网关。Skeleton:这是驻留在服务器端的对象。存根与此骨架通信以将请求传递给远程对象。RRL(远程引用层):这是管理客户端对远程对象的引用的层。
RMI 注册表是一个名称空间,所有 服务器对象都放置在该名称空间上。每次服务器创建一个对象时,它都会向 RMIregistry 注册这个对象(使用bind()或reBind()方法)。这些是使用称为bind name的唯一名称注册的。要调用远程对象,客户端需要该对象的引用。那时,客户端使用其绑定名称(使用lookup()方法)从注册表中获取对象。
创建远程服务接口,继承Remote接口,每个方法需要抛出RemoteException异常:
package com.wu.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;
// 远程接口
public interface DateService extends Remote {
public String printDate() throws RemoteException;
public String printSender(String sender) throws RemoteException;
}
实现远程服务接口类,继承UnicastRemoteObject类:
package com.wu.rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;
// 远程接口实现类
public class DateServiceImpl extends UnicastRemoteObject
implements DateService{
public DateServiceImpl() throws RemoteException{}
@Override
public String printDate() throws RemoteException{
return "服务器时间:" + new Date();
}
@Override
public String printSender(String sender) throws RemoteException{
return "客户端:" + sender;
}
}
创建服务端:
package com.wu.rmi;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class SimpleDateServer {
public static void main(String[] args){
int port = 1111;
try{
// 创建对象
DateServiceImpl dateService1 = new DateServiceImpl();
DateServiceImpl dateService2 = new DateServiceImpl();
// 创建并启动注册器
LocateRegistry.createRegistry(port); // 服务器端口号设置
// 注册并绑定远程对象
Naming.bind("rmi://192.168.56.1:1111/print1",dateService1);
Naming.bind("rmi://192.168.56.1:1111/print2",dateService2);
System.out.println("========== 启动RMI服务成功! ==========");
}catch(RemoteException e){
e.printStackTrace();
}catch (MalformedURLException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
}
创建客户端:
package com.wu.rmi;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class SimpleClient {
public static void main(String[] args){
try{
String sender1 = "发送方1";
String sender2 = "发送方2";
DateService dateService1 = (DateService) Naming.lookup("rmi://192.168.56.1:1111/print1");
DateService dateService2 = (DateService) Naming.lookup("rmi://192.168.56.1:1111/print2");
System.out.println(dateService1.printSender(sender1) +", "+dateService1.printDate());
Thread.sleep(1000);
System.out.println(dateService1.printSender(sender2) +", "+dateService2.printDate());
}catch(RemoteException e){
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
服务端结果:
========== 启动RMI服务成功! ==========
客户端结果:
客户端:发送方1, 服务器时间:Tue Aug 17 19:17:28 CST 2021
客户端:发送方2, 服务器时间:Tue Aug 17 19:17:29 CST 2021