需要注意的是,由于底层的网络通讯是基于二进制格式的,因此这里Stub传给通讯工具类的数据也必须是二进制,比如calculator.add(1,2),你必须把参数值1和2放到一个Request对象里头(这个Request对象当然不只这些信息,还包括要调用哪个服务的哪个RPC接口等其他信息),然后序列化为二进制,再传给通讯工具类,这一点也将在下面的代码实现中体现;二进制的数据传到Service B这一边了,Service B当然也有自己的通讯工具,通过这个通讯工具接收二进制的请求;既然数据是二进制的,那么自然要进行反序列化了,将二进制的数据反序列化为请求对象,然后将这个请求对象交给Service B的Stub处理;和之前的Service A的Stub一样,这里的Stub也同样是个“假玩意”,它所负责的,只是去解析请求对象,知道调用方要调的是哪个RPC接口,传进来的参数又是什么,然后再把这些参数传给对应的RPC接口,也就是Calculator的实际实现类去执行。很明显,如果是Java,那这里肯定用到了反射。RPC接口执行完毕,返回执行结果,现在轮到Service B要把数据发给Service A了,怎么发?一样的道理,一样的流程,只是现在Service B变成了Client,Service A变成了Server而已:Service B反序列化执行结果->传输给Service A->Service A反序列化执行结果 -> 将结果返回给Application,完毕。
理论的讲完了,是时候把理论变成实践了。
把理论变成实践
本文的示例代码,可到Github下载。
首先是Client端的应用层怎么发起RPC,ComsumerApp:
publicclassComsumerApp{publicstaticvoidmain(String[]args){Calculatorcalculator=newCalculatorRemoteImpl();intresult=calculator.add(1,2);}}
通过一个CalculatorRemoteImpl,我们把RPC的逻辑封装进去了,客户端调用时感知不到远程调用的麻烦。下面再来看看CalculatorRemoteImpl,代码有些多,但是其实就是把上面的2、3、4几个步骤用代码实现了而已,Ca