三.ipc.Client源码分析
同样,为了对Client类有个初步的了解,我们也先罗列几个我们感兴趣的内部类:
Call :用于封装Invocation对象,作为VO,写到服务端,同时也用于存储从服务端返回的数据
Connection :用以处理远程连接对象。继承了Thread
ConnectionId :唯一确定一个连接
问题1:客户端和服务端的连接是怎样建立的?
下面我们来看看Client类中的cal()方法吧:
代码三:
public Writable call(Writable param, ConnectionId remoteId) throws InterruptedException, IOException { Call call = new Call(param); //将传入的数据封装成call对象 Connection connection = getConnection(remoteId, call); //获得一个连接 connection.sendParam(call); // 向服务端发送call对象 boolean interrupted = false; synchronized (call) { while (!call.done) { try { call.wait(); // 等待结果的返回,在Call类的callComplete()方法里有notify()方法用于唤醒线程 } catch (InterruptedException ie) { // 因中断异常而终止,设置标志interrupted为true interrupted = true; } } if (interrupted) { Thread.currentThread().interrupt(); } if (call.error != null) { if (call.error instanceof RemoteException) { call.error.fillInStackTrace(); throw call.error; } else { // 本地异常 throw wrapException(remoteId.getAddress(), call.error); } } else { return call.value; //返回结果数据 } } }具体代码的作用我已做了注释,所以这里不再赘述。但到目前为止,你依然不知道RPC机制底层的网络连接是怎么建立的。呵呵,那我们只好再去深究了,分析代码后,我们会发现和网络通信有关的代码只会是下面的两句了:
代码四:
Connection connection = getConnection(remoteId, call); //获得一个连接 connection.sendParam(call); // 向服务端发送call对象先看看是怎么获得一个到服务端的连接吧,下面贴出ipc.Client类中的getConnection()方法。