ClientCnxn
为客户端发送请求到服务端,管理底层IO连接。 将用户调用的请求对象(RequestHeader、Request)封装成Packet对象,存入发送队列。内部有一个线程会不断读取发送队列中的Packet对象,通过NIO将Packet对象发送到服务端,然后将Packet对象放入pending队列,该线程会不断读取服务端的返回信息,并且将结果设置到Packet对象的Response,ReplyHeader对象中。
//等待发送的数据包队列 private final LinkedList<Packet> outgoingQueue = new LinkedList<Packet>(); //发送后等待结果的数据包队列 private final LinkedList<Packet> pendingQueue = new LinkedList<Packet>(); class SendThread extends Thread { boolean doIO() throws InterruptedException, IOException { ...if (!outgoingQueue.isEmpty()) { ByteBuffer pbb = outgoingQueue.getFirst().bb; sock.write(pbb); if (!pbb.hasRemaining()) { sentCount++; Packet p = outgoingQueue.removeFirst(); if (p.header != null && p.header.getType() != OpCode.ping && p.header.getType() != OpCode.auth) { pendingQueue.add(p); } } } } ... } ... @Override public void run() { ...while (zooKeeper.state.isAlive()) { ...if (doIO()) { lastHeard = now; } ... } ... }
通信协议
通信协议即客户端和服务端之间的序列号和反序列号方式。详见zookeeper源码之通信协议。