RPC是双向通信的Protocol
1.RPC,Protocol公共子类Skeleton
public abstract class Skeleton {
private volatile Object note;
Skeleton() {
}
abstract void setTransport(Transport transport);
abstract void _unmarshal(OctetsStream os) throws MarshalException;
abstract void dispatch();
public abstract int getType();
public abstract void process() throws Exception;
public final Object getNote() {
return note;
}
public final void setNote(Object note) {
this.note = note;
}
}
2.发送RPC协议
public final void send(Transport transport)
throws InstantiationException, SizePolicyException, CodecException, ClassCastException {
try {
//RPC中区分请求与相应
isRequest = true;
Manager manager = transport.getManager();
sid = ((SupportRpcContext) manager).addContext(protocol);
checkSend(transport, new OctetsStream().marshal(protocol));
//定时器超时处理
if (future == null)
protocol.future = Engine.getProtocolScheduler().schedule(new Timeout(manager, sid), getTimeout(),
TimeUnit.MILLISECONDS);
} catch (RuntimeException e) {
throw new CodecException(e);
}
}
3.对方收到协议处理逻辑后调用response响应
public final void response()
throws InstantiationException, SizePolicyException, CodecException, ClassCastException {
try {
clearRequest().checkSend(protocol.getTransport(), new OctetsStream().marshal(protocol));
} catch (RuntimeException e) {
throw new CodecException(e);
}
}
4.发送方收到response信息处理
@Override
final void dispatch() {
//请求rpc直接当协议处理
if (isRequest) {
protocol.dispatch();
return;
}
// response
InnerProtocol inner = ((SupportRpcContext) protocol.getManager()).removeContext(sid, protocol);
if (null == inner) {
if (Trace.isInfoEnabled())
Trace.info("limax.net.Rpc.response context lost! " + this);
return;
}
if (inner.future != null)
inner.future.cancel(false);
Rpc<A, R> rpc = inner.getRpc().clearRequest().setResult(result);
rpc.setTransport(getTransport());
if (rpc.future != null) {
if (Trace.isDebugEnabled())
Trace.debug("limax.net.Rpc.response with submit " + this);
rpc.future.set(result);
return;
}
if (Trace.isDebugEnabled())
Trace.debug("limax.net.Rpc.response execute " + this);
inner.dispatch();
}
//主动调用onClient处理响应信息
public void process() throws Exception {
if (isRequest) {
onServer();
response();
} else {
_onClient();
}
}
5.总结
(1)RPC在Global模块中使用,用于全局名字分配,此时可以在一个过程中确认是否调用成功
(2)RPC可以充分利用资源,多机交互。