源码级强力分析Hadoop的RPC机制(3)

三.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()方法。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/973f4028c89c9cbacf526d4b5acb8f29.html