您的位置 首页 java

Java进阶:远程过程调用(RPC)及回调方法(二)

回调方法

在客户端实例化一个远程( Remote )对象,调用远程方法时作为 参数 传递给服务端,服务端通过调用这个远程对象的方法实现回调。

在客户端编写一个供回调远程接口,这次叫ICallback,而非IMethod。

import  Java .rmi.Remote;
import java.rmi.RemoteException;
public interface ICallback extends Remote {
 //供服务端调用,同样 code 参数用于标识两台
 void callback(int code) throws RemoteException;
}
 

同样的 extends UnicastRemoteObject implements I callback

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class CallbackImpl extends UnicastRemoteObject implements ICallback {
 protected CallbackImpl() throws RemoteException {
 }
 @ Override 
 public void callback(int code) throws RemoteException {
 System.out.println("From " + code + " : Roger that.");
 }
}
 

修改之前的接口

增加一个方法call(ICallback callback)

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IMethod extends Remote {
 void sayHi(int code) throws RemoteException;
 void call(ICallback callback) throws RemoteException;
}
 

同时在服务端修改实现类

 ... ...
 @Override
 public void call(ICallback callback) throws RemoteException {
 System.out.println("From Client" + " : Hello");
 callback.callback( Runtime .getRuntime().hashCode());
 }
 ... ...
 

客户端调用远程方法

//实例化回调对象

ICallback callback = new CallbackImpl();

//调用远程方法

method.call(callback);

//回收回调对象

UnicastRemoteObject.unexportObject(callback, false);

可以看到,我们新建了一个远程对象ICallback,并在客户端实现了它。将其作为参数,传递到远程对象的IMethod的call方法。而IMethod的实现则是在服务端完成的。即是,在客户端调用了服务端的call()方法,而服务端则调用了客户端的callback()方法。

运行

同样,先运行起服务端,再运行客户端

可以在服务端的控制台看见输出

From Client : Hello
 

在客户端的控制台看见输出

From 服务端hashCode : Roger that.
 

说明客户端调用了服务端的call方法,服务端在call方法中调用了客户端传递过来的callback对象的callback方法,并传递过去了本地Runtime的hashCode。

常见的问题

抛出异常

java .rmi.server.ExportException: remote object implements illegal remote interface;

原因:Remote接口中声明的方法必须声明throws RemoteException

java.rmi.server.ExportExcept io n: internal error: ObjID already in use

原因:端口被占用或重复在同一端口号创建远程对象注册表

java.net.MalformedURLException: invalid URL scheme

原因:绑定远程对象时的name字符串必须符合URL格式,且前面的协议名必须为rmi://或者省略

程序不能正常结束

需要回收导出的远程对象,调用UnicastRemoteObject类的方法unexportObject(Remote obj, boolean force)

//回收远程对象

UnicastRemoteObject.unexportObject(object, false);

另外,上文编写远程接口实现类时,可以不使用extends扩展自UnicastRemoteObject。

那么这时候要求这个实现类实现可 序列化 接口Serializable,并且在绑定端口时通过调用UnicastRemoteObject类的exportObject方法获取这个远程对象的代理对象,再调用Naming.bind进行绑定。

import java.io.Serializable;
import java.rmi.RemoteException;
public class MethodImpl implements IMethod, Serializable {
 protected MethodImpl() throws RemoteException {
 }

//实例化远程对象
IMethod method = new MethodImpl();
//获取代理对象
Remote obj = UnicastRemoteObject.exportObject(method, 10086);
//绑定端口
Naming.bind("// localhost :10086/method", obj);
 

文章来源:智云一二三科技

文章标题:Java进阶:远程过程调用(RPC)及回调方法(二)

文章地址:https://www.zhihuclub.com/170012.shtml

关于作者: 智云科技

热门文章

网站地图