我如何实现一个Java RMI远程方法调用的案例?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2342个文字,预计阅读时间需要10分钟。
自己简单写了一个Java RMI(远程方法调用)的实现案例。为了更好地理解RMI(远程方法调用)和序列化的意义等,花费了三天多的时间。高能预警!高能预警!高能预警!
自己简单写了个Java RMI(远程方法调用)的实现案例。
为了更好理解RMI(远程方法调用)、序列化的意义等等,花费三天多的时间肝了一个Java RMI的实现案例。
!!!高能预警!!!代码量有点大,先附上了简图用于理解
整个过程分为两大步
- 第一步--注册过程:客户端通过指定路由获取注册中心指定的远程客户端对象;
- 第二部--服务调用过程:客户端通过远程客户端对象访问远程服务端(代理服务)从而访问到真实服务的实现
1.定义远程标记接口调整为舒适的姿势,慢慢看…… 废话少说,上代码!!!
面向接口编程,具体作用看后面的代码怎么使用
//标记接口:直接或间接实现MyRMI接口将获得远程调用的能力
publicinterfaceMyRMI{
}
2.编写RMI 服务注册中心
注册中心类:用于注册服务和获取服务,核心是hashMap路由表对象
/**
*注册中心:维护服务发布的注册表
*/
publicclassMyRMIRegistry{
//默认端口
publicfinalintREGISTRY_PORT=10099;
privateStringhost;
privateintport;
privateMap<String,MyRMI>bindings;
publicMyRMIRegistry(intport){
this.port=port;
}
publicMyRMIRegistry(Stringhost,intport){
this.host=host;
this.port=port;
}
publicvoidcreateRegistry(StringserverName,MyRMImyRMI){
//注册服务,并开启服务
this.bindings=newHashMap<>();
Stringhost=null;
try{
host=Inet4Address.getLocalHost().getHostAddress();
}catch(UnknownHostExceptione){
e.printStackTrace();
}
//路由规则可自行定义,只要能确保Key唯一即可
Stringbinding="myrmi://"+host+":"+port+"/"+serverName;
this.bindings.put("myrmi://"+host+":"+port+"/"+serverName,myRMI);
System.out.println("注册的服务有:"+bindings.keySet().toString());
MyRMIRegistryServermyRMIRegistryServer=newMyRMIRegistryServer(this.port,this.bindings);
Executors.newCachedThreadPool().submit(myRMIRegistryServer);//线程池启动服务
}
publicMyRMIgetRegistry(StringserverName){
Socketsocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
MyRMImyRMI=null;
//通过
try{
socket=newSocket(host,port);
out=newObjectOutputStream(socket.getOutputStream());
out.writeObject("myrmi://"+host+":"+port+"/"+serverName);
in=newObjectInputStream(socket.getInputStream());
myRMI=(MyRMI)in.readObject();
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
returnmyRMI;
}
}
RMI 注册中心获取服务的线程:启动注册中心服务,等待客户端来获取路由表中的远程客户端
/**
*RMI注册中心获取服务线程
*/
publicclassMyRMIRegistryServerimplementsRunnable{
privateintport;
privateMap<String,MyRMI>bindings;
publicMyRMIRegistryServer(Integerport,Map<String,MyRMI>bindings){
this.port=port;
this.bindings=bindings;
}
@Override
publicvoidrun(){
ServerSocketserverSocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
try{
serverSocket=newServerSocket(this.port);
while(true){
Socketsocket=serverSocket.accept();
in=newObjectInputStream(socket.getInputStream());
out=newObjectOutputStream(socket.getOutputStream());
//看看客户端想要什么服务
StringserverName=(String)in.readObject();
Iteratoriterator=bindings.keySet().iterator();
while(iterator.hasNext()){
Stringkey=(String)iterator.next();
if(serverName.equals(key)){
//给客户端响应服务对象
MyRMImyRMI=bindings.get(key);
out.writeObject(myRMI);
}
}
}
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}finally{
//异常后进入
try{
if(out!=null)out.close();
if(in!=null)in.close();
if(serverSocket!=null)serverSocket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
3.定义要发布的服务接口
需要提供RMI服务的接口,必须继承自定义的MyRMI标记接口
/**
*服务接口
*/
publicinterfaceHelloextendsMyRMI{
publicStringsayHello(Stringname);
}
4.服务用到的实体类
/**
*对象数据类:Person
*/
publicclassPersonimplementsSerializable{
//序列化版本UID
privatestaticfinallongserialVersionUID=1L;
privateStringname;
privateintage;
privateStringsex;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
publicStringgetSex(){
returnsex;
}
publicvoidsetSex(Stringsex){
this.sex=sex;
}
@Override
publicStringtoString(){
return"Person{"+"name='"+name+",age="+age+",sex='"+sex+'}';
}
publicPerson(){
}
publicPerson(Stringname,Integerage,Stringsex){
this.name=name;
this.age=age;
this.sex=sex;
}
}
5.实现要发布的服务接口
/**
*对外提供的服务实现
*/
publicclassHelloImplimplementsHello{
privatestaticFilefile=newFile("D:/HelloRMI.txt");
privatestaticList<Person>list=newArrayList<>();
@Override
publicStringsayHello(Stringname){
Stringresult="没有获取到"+name+"的信息";
try{
List<Person>personList=readList();
for(Personperson:personList){
if(person.getName().equals(name)){
result="Hello,welcometotheRMI!"
+"姓名:"+name+"年龄:"+person.getAge()+"性别:"+person.getSex();
}
}
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
returnresult;
}
/**
*生成数据,为测试做准备
*@paramargs
*@throwsIOException
*@throwsClassNotFoundException
*/
publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{
//数据准备:集合类都实现了序列化接口Serializable
list.add(newPerson("张三",38,"男"));
list.add(newPerson("李四",38,"男"));
list.add(newPerson("如花",18,"女"));
//持久化对象数据
writerList(list);
//查询持久化对象数据
List<Person>personList=readList();
System.out.println("遍历持久化对象数据>");
for(Personperson:personList){
System.out.println(person);
if(person.getAge()==38){
person.setAge(18);
}
}
}
publicstaticvoidwriterList(List<Person>list)throwsIOException{
ObjectOutputStreamobjectOutputStream=newObjectOutputStream(newFileOutputStream(file));
objectOutputStream.writeObject(list);
objectOutputStream.close();
}
publicstaticList<Person>readList()throwsIOException,ClassNotFoundException{
//读取普通文件反序列化
ObjectInputStreamobjectInputStream=newObjectInputStream(newFileInputStream(file));
List<Person>personList=(List<Person>)objectInputStream.readObject();
objectInputStream.close();
returnpersonList;
}
}
6.远程客户端的线程类
用于自动生成服务接口(继承了MyRMI标记接口)的远程客户端类:这个类原本是通用类实现,为了方便实现,就直接实现Hello接口了
/**
*远程客户端的线程类的生成:
*为了方便实现,这边直接实现服务接口编写
*/
publicclassHelloClientThreadimplementsHello,Serializable{
//序列化版本UID
privatestaticfinallongserialVersionUID=1L;
privateMap<String,Object>map=newHashMap<>();//报文对象:方法名和参数对象
privateStringip;
privateintport;
publicHelloClientThread(Stringip,intport){
this.ip=ip;
this.port=port;
}
@Override
publicStringsayHello(Stringname){
map.put("sayHello",name);
Stringresult=(String)send();
returnresult;
}
privateObjectsend(){
Objecto=null;
Socketsocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
try{
socket=newSocket(ip,port);
out=newObjectOutputStream(socket.getOutputStream());
in=newObjectInputStream(socket.getInputStream());
//告诉服务端我要调用什么服务
out.writeObject(map);
//获取服务实现对象
o=in.readObject();
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}finally{
try{
if(out!=null)out.close();
if(in!=null)in.close();
if(socket!=null)socket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
returno;
}
}
7.远程服务端的线程类
用于自动生成服务接口(继承了MyRMI标记接口)的远程服务端类:这个类原本也是通用类实现,为了方便实现,部分代码尚未做到解耦通用
/**
*远程服务端的线程类的生成:
*为了方便实现,这边直接实现服务线程类
*/
publicclassHelloServerThreadimplementsRunnable{
privateIntegerport;
privateMyRMImyRMI;
publicHelloServerThread(Integerport,MyRMImyRMI){
this.port=port;
this.myRMI=myRMI;
}
@Override
publicvoidrun(){
ServerSocketserverSocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
try{
serverSocket=newServerSocket(this.port);
while(true){
Socketsocket=serverSocket.accept();
in=newObjectInputStream(socket.getInputStream());
out=newObjectOutputStream(socket.getOutputStream());
//看看客户端想要什么服务
Mapmap=(Map)in.readObject();
Iteratoriterator=map.keySet().iterator();
while(iterator.hasNext()){
Stringkey=(String)iterator.next();
if("sayHello".equals(key)){
//给客户端响应服务对象
Hellohello=(Hello)myRMI;
Stringresult=hello.sayHello((String)map.get(key));
out.writeObject(result);
}
}
}
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}finally{
//异常后进入
try{
if(out!=null)out.close();
if(in!=null)in.close();
if(serverSocket!=null)serverSocket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
8.远程客户端生成和远程服务端生成和启动的类
/**
*远程客户端生成和远程服务端生成和启动的类
*/
publicclassRemoteSocketObject{
//默认端口
privateintport=18999;
//指定远程通讯端口和代理服务
publicMyRMIcreateRemoteClient(MyRMImyRMI,intport){
if(port>0)
this.port=port;
MyRMImyRMIClient=null;
try{
//生成底层通讯服务端,并启动
HelloServerThreadhelloServerThread=newHelloServerThread(this.port,myRMI);
Executors.newCachedThreadPool().submit(helloServerThread);//线程池启动服务
//生成底层通讯客户端
StringlocalHost=Inet4Address.getLocalHost().getHostAddress();
System.out.println("host="+localHost+",port="+this.port);
myRMIClient=newHelloClientThread(localHost,this.port);
}catch(Exceptione){
e.printStackTrace();
}
returnmyRMIClient;
}
}
9.服务发布类
/**
*RMI服务发布类
*/
publicclassHelloServer{
publicstaticvoidmain(String[]args){
System.out.println("CreateHelloRemoteMethodInvocation...");
//实例化一个Hello
Hellohello=newHelloImpl();
//转换成远程服务,并提供远程客户端
HelloremoteClient=(Hello)newRemoteSocketObject().createRemoteClient(hello,0);
//将服务实现托管到Socket服务
MyRMIRegistrymyRMIRegistry=newMyRMIRegistry(16000);
//开启线程服务
myRMIRegistry.createRegistry("Hello",remoteClient);
}
}
10.客户端测试类
/**
*客户端测试类
*客户端只知道服务接口、服务发布的地址和服务发布的名称
*/
publicclassTestHello{
publicstaticvoidmain(String[]args){
//注意不是127.0.0.1,不知道host的看server端启动后打印的信息
//端口16000是注册中心的端口,底层代理服务的端口客户端无需知道
MyRMIRegistryclient=newMyRMIRegistry("192.168.233.1",16000);
Hellohello=(Hello)client.getRegistry("Hello");
System.out.println(hello.sayHello("张三"));
}
}
11.总结
所有代码整下来,在真正的场景中:
客户端只知道:TestHello类、Hello接口定义、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中只知道Key,不知道具体值);
服务端只知道:Hello接口、HelloImpl服务实现类、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中知道Key和具体值);
关于其他的代码实现都是无感的,为了简单实现远程客户端和远程服务端,将服务接口耦合到两者上了,未做到解耦通用。
Java往期文章
Java全栈学习路线、学习资源和面试题一条龙
我心里优秀架构师是怎样的?
免费下载经典编程书籍
更多优质文章和资源
本文共计2342个文字,预计阅读时间需要10分钟。
自己简单写了一个Java RMI(远程方法调用)的实现案例。为了更好地理解RMI(远程方法调用)和序列化的意义等,花费了三天多的时间。高能预警!高能预警!高能预警!
自己简单写了个Java RMI(远程方法调用)的实现案例。
为了更好理解RMI(远程方法调用)、序列化的意义等等,花费三天多的时间肝了一个Java RMI的实现案例。
!!!高能预警!!!代码量有点大,先附上了简图用于理解
整个过程分为两大步
- 第一步--注册过程:客户端通过指定路由获取注册中心指定的远程客户端对象;
- 第二部--服务调用过程:客户端通过远程客户端对象访问远程服务端(代理服务)从而访问到真实服务的实现
1.定义远程标记接口调整为舒适的姿势,慢慢看…… 废话少说,上代码!!!
面向接口编程,具体作用看后面的代码怎么使用
//标记接口:直接或间接实现MyRMI接口将获得远程调用的能力
publicinterfaceMyRMI{
}
2.编写RMI 服务注册中心
注册中心类:用于注册服务和获取服务,核心是hashMap路由表对象
/**
*注册中心:维护服务发布的注册表
*/
publicclassMyRMIRegistry{
//默认端口
publicfinalintREGISTRY_PORT=10099;
privateStringhost;
privateintport;
privateMap<String,MyRMI>bindings;
publicMyRMIRegistry(intport){
this.port=port;
}
publicMyRMIRegistry(Stringhost,intport){
this.host=host;
this.port=port;
}
publicvoidcreateRegistry(StringserverName,MyRMImyRMI){
//注册服务,并开启服务
this.bindings=newHashMap<>();
Stringhost=null;
try{
host=Inet4Address.getLocalHost().getHostAddress();
}catch(UnknownHostExceptione){
e.printStackTrace();
}
//路由规则可自行定义,只要能确保Key唯一即可
Stringbinding="myrmi://"+host+":"+port+"/"+serverName;
this.bindings.put("myrmi://"+host+":"+port+"/"+serverName,myRMI);
System.out.println("注册的服务有:"+bindings.keySet().toString());
MyRMIRegistryServermyRMIRegistryServer=newMyRMIRegistryServer(this.port,this.bindings);
Executors.newCachedThreadPool().submit(myRMIRegistryServer);//线程池启动服务
}
publicMyRMIgetRegistry(StringserverName){
Socketsocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
MyRMImyRMI=null;
//通过
try{
socket=newSocket(host,port);
out=newObjectOutputStream(socket.getOutputStream());
out.writeObject("myrmi://"+host+":"+port+"/"+serverName);
in=newObjectInputStream(socket.getInputStream());
myRMI=(MyRMI)in.readObject();
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
returnmyRMI;
}
}
RMI 注册中心获取服务的线程:启动注册中心服务,等待客户端来获取路由表中的远程客户端
/**
*RMI注册中心获取服务线程
*/
publicclassMyRMIRegistryServerimplementsRunnable{
privateintport;
privateMap<String,MyRMI>bindings;
publicMyRMIRegistryServer(Integerport,Map<String,MyRMI>bindings){
this.port=port;
this.bindings=bindings;
}
@Override
publicvoidrun(){
ServerSocketserverSocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
try{
serverSocket=newServerSocket(this.port);
while(true){
Socketsocket=serverSocket.accept();
in=newObjectInputStream(socket.getInputStream());
out=newObjectOutputStream(socket.getOutputStream());
//看看客户端想要什么服务
StringserverName=(String)in.readObject();
Iteratoriterator=bindings.keySet().iterator();
while(iterator.hasNext()){
Stringkey=(String)iterator.next();
if(serverName.equals(key)){
//给客户端响应服务对象
MyRMImyRMI=bindings.get(key);
out.writeObject(myRMI);
}
}
}
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}finally{
//异常后进入
try{
if(out!=null)out.close();
if(in!=null)in.close();
if(serverSocket!=null)serverSocket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
3.定义要发布的服务接口
需要提供RMI服务的接口,必须继承自定义的MyRMI标记接口
/**
*服务接口
*/
publicinterfaceHelloextendsMyRMI{
publicStringsayHello(Stringname);
}
4.服务用到的实体类
/**
*对象数据类:Person
*/
publicclassPersonimplementsSerializable{
//序列化版本UID
privatestaticfinallongserialVersionUID=1L;
privateStringname;
privateintage;
privateStringsex;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
publicStringgetSex(){
returnsex;
}
publicvoidsetSex(Stringsex){
this.sex=sex;
}
@Override
publicStringtoString(){
return"Person{"+"name='"+name+",age="+age+",sex='"+sex+'}';
}
publicPerson(){
}
publicPerson(Stringname,Integerage,Stringsex){
this.name=name;
this.age=age;
this.sex=sex;
}
}
5.实现要发布的服务接口
/**
*对外提供的服务实现
*/
publicclassHelloImplimplementsHello{
privatestaticFilefile=newFile("D:/HelloRMI.txt");
privatestaticList<Person>list=newArrayList<>();
@Override
publicStringsayHello(Stringname){
Stringresult="没有获取到"+name+"的信息";
try{
List<Person>personList=readList();
for(Personperson:personList){
if(person.getName().equals(name)){
result="Hello,welcometotheRMI!"
+"姓名:"+name+"年龄:"+person.getAge()+"性别:"+person.getSex();
}
}
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
returnresult;
}
/**
*生成数据,为测试做准备
*@paramargs
*@throwsIOException
*@throwsClassNotFoundException
*/
publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{
//数据准备:集合类都实现了序列化接口Serializable
list.add(newPerson("张三",38,"男"));
list.add(newPerson("李四",38,"男"));
list.add(newPerson("如花",18,"女"));
//持久化对象数据
writerList(list);
//查询持久化对象数据
List<Person>personList=readList();
System.out.println("遍历持久化对象数据>");
for(Personperson:personList){
System.out.println(person);
if(person.getAge()==38){
person.setAge(18);
}
}
}
publicstaticvoidwriterList(List<Person>list)throwsIOException{
ObjectOutputStreamobjectOutputStream=newObjectOutputStream(newFileOutputStream(file));
objectOutputStream.writeObject(list);
objectOutputStream.close();
}
publicstaticList<Person>readList()throwsIOException,ClassNotFoundException{
//读取普通文件反序列化
ObjectInputStreamobjectInputStream=newObjectInputStream(newFileInputStream(file));
List<Person>personList=(List<Person>)objectInputStream.readObject();
objectInputStream.close();
returnpersonList;
}
}
6.远程客户端的线程类
用于自动生成服务接口(继承了MyRMI标记接口)的远程客户端类:这个类原本是通用类实现,为了方便实现,就直接实现Hello接口了
/**
*远程客户端的线程类的生成:
*为了方便实现,这边直接实现服务接口编写
*/
publicclassHelloClientThreadimplementsHello,Serializable{
//序列化版本UID
privatestaticfinallongserialVersionUID=1L;
privateMap<String,Object>map=newHashMap<>();//报文对象:方法名和参数对象
privateStringip;
privateintport;
publicHelloClientThread(Stringip,intport){
this.ip=ip;
this.port=port;
}
@Override
publicStringsayHello(Stringname){
map.put("sayHello",name);
Stringresult=(String)send();
returnresult;
}
privateObjectsend(){
Objecto=null;
Socketsocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
try{
socket=newSocket(ip,port);
out=newObjectOutputStream(socket.getOutputStream());
in=newObjectInputStream(socket.getInputStream());
//告诉服务端我要调用什么服务
out.writeObject(map);
//获取服务实现对象
o=in.readObject();
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}finally{
try{
if(out!=null)out.close();
if(in!=null)in.close();
if(socket!=null)socket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
returno;
}
}
7.远程服务端的线程类
用于自动生成服务接口(继承了MyRMI标记接口)的远程服务端类:这个类原本也是通用类实现,为了方便实现,部分代码尚未做到解耦通用
/**
*远程服务端的线程类的生成:
*为了方便实现,这边直接实现服务线程类
*/
publicclassHelloServerThreadimplementsRunnable{
privateIntegerport;
privateMyRMImyRMI;
publicHelloServerThread(Integerport,MyRMImyRMI){
this.port=port;
this.myRMI=myRMI;
}
@Override
publicvoidrun(){
ServerSocketserverSocket=null;
ObjectOutputStreamout=null;
ObjectInputStreamin=null;
try{
serverSocket=newServerSocket(this.port);
while(true){
Socketsocket=serverSocket.accept();
in=newObjectInputStream(socket.getInputStream());
out=newObjectOutputStream(socket.getOutputStream());
//看看客户端想要什么服务
Mapmap=(Map)in.readObject();
Iteratoriterator=map.keySet().iterator();
while(iterator.hasNext()){
Stringkey=(String)iterator.next();
if("sayHello".equals(key)){
//给客户端响应服务对象
Hellohello=(Hello)myRMI;
Stringresult=hello.sayHello((String)map.get(key));
out.writeObject(result);
}
}
}
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}finally{
//异常后进入
try{
if(out!=null)out.close();
if(in!=null)in.close();
if(serverSocket!=null)serverSocket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
8.远程客户端生成和远程服务端生成和启动的类
/**
*远程客户端生成和远程服务端生成和启动的类
*/
publicclassRemoteSocketObject{
//默认端口
privateintport=18999;
//指定远程通讯端口和代理服务
publicMyRMIcreateRemoteClient(MyRMImyRMI,intport){
if(port>0)
this.port=port;
MyRMImyRMIClient=null;
try{
//生成底层通讯服务端,并启动
HelloServerThreadhelloServerThread=newHelloServerThread(this.port,myRMI);
Executors.newCachedThreadPool().submit(helloServerThread);//线程池启动服务
//生成底层通讯客户端
StringlocalHost=Inet4Address.getLocalHost().getHostAddress();
System.out.println("host="+localHost+",port="+this.port);
myRMIClient=newHelloClientThread(localHost,this.port);
}catch(Exceptione){
e.printStackTrace();
}
returnmyRMIClient;
}
}
9.服务发布类
/**
*RMI服务发布类
*/
publicclassHelloServer{
publicstaticvoidmain(String[]args){
System.out.println("CreateHelloRemoteMethodInvocation...");
//实例化一个Hello
Hellohello=newHelloImpl();
//转换成远程服务,并提供远程客户端
HelloremoteClient=(Hello)newRemoteSocketObject().createRemoteClient(hello,0);
//将服务实现托管到Socket服务
MyRMIRegistrymyRMIRegistry=newMyRMIRegistry(16000);
//开启线程服务
myRMIRegistry.createRegistry("Hello",remoteClient);
}
}
10.客户端测试类
/**
*客户端测试类
*客户端只知道服务接口、服务发布的地址和服务发布的名称
*/
publicclassTestHello{
publicstaticvoidmain(String[]args){
//注意不是127.0.0.1,不知道host的看server端启动后打印的信息
//端口16000是注册中心的端口,底层代理服务的端口客户端无需知道
MyRMIRegistryclient=newMyRMIRegistry("192.168.233.1",16000);
Hellohello=(Hello)client.getRegistry("Hello");
System.out.println(hello.sayHello("张三"));
}
}
11.总结
所有代码整下来,在真正的场景中:
客户端只知道:TestHello类、Hello接口定义、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中只知道Key,不知道具体值);
服务端只知道:Hello接口、HelloImpl服务实现类、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中知道Key和具体值);
关于其他的代码实现都是无感的,为了简单实现远程客户端和远程服务端,将服务接口耦合到两者上了,未做到解耦通用。
Java往期文章
Java全栈学习路线、学习资源和面试题一条龙
我心里优秀架构师是怎样的?
免费下载经典编程书籍
更多优质文章和资源

