建立连接会话
建立连接会话请求响应没有头部
建立连接会话请求
class ConnectRequest {
int protocolVersion;
long lastZxidSeen;
int timeOut;
long sessionId;
buffer passwd;
}
建立连接会话响应
class ConnectResponse {
int protocolVersion;
int timeOut;
long sessionId;
buffer passwd;
}
public class ConnectTest {
private static final Logger log = LoggerFactory.getLogger(ConnectTest.class);
private static SocketChannel channel;
@BeforeClass
public static void initialize() throws IOException {
channel = SocketChannel.open();
SocketAddress socketAddress = new InetSocketAddress("localhost", 2191);
channel.connect(socketAddress);
}
private static class WriteWorker extends Thread {
public void run() {
//for (;;) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
ConnectRequest connectRequest = new ConnectRequest(0, 0, 10000, 0, new byte[16]);
boa.writeInt(-1, "len"); // We'll fill this in later
connectRequest.serialize(boa, "connect");
boa.writeBool(true, "readOnly");
baos.close();
ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
bb.putInt(bb.capacity() - 4);
bb.rewind();
channel.write(bb);
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//}
}
}
private static class ReaderWorker extends Thread {
public void run() {
for (;;) {
try {
ByteBuffer lenBuffer = ByteBuffer.allocateDirect(4);
while (true) {
channel.read(lenBuffer);
if (! lenBuffer.hasRemaining()) {
break;
}
}
lenBuffer.flip();
int len = lenBuffer.getInt();
if (len < 0 || len >= ClientCnxn.packetLen) {
throw new IOException("Packet len" + len + " is out of range!");
}
ByteBuffer buffer = ByteBuffer.allocate(len);
while (true) {
channel.read(buffer);
if (! buffer.hasRemaining()) {
break;
}
}
buffer.flip();
ByteBufferInputStream bbis = new ByteBufferInputStream(buffer);
BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
ConnectResponse conRsp = new ConnectResponse();
conRsp.deserialize(bbia, "connect");
// read "is read-only" flag
boolean isRO = false;
try {
isRO = bbia.readBool("readOnly");
} catch (IOException e) {
// this is ok -- just a packet from an old server which
// doesn't contain readOnly field
log.warn("Connected to an old server; r-o mode will be unavailable");
}
System.out.println(ToStringBuilder.reflectionToString(conRsp, ToStringStyle.MULTI_LINE_STYLE));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void connect() throws IOException {
Thread wt = new WriteWorker();
wt.start();
Thread rt = new ReaderWorker();
rt.start();
try {
wt.join();
rt.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
启动运行后:
服务器打印出如下日志:
2017-04-14 20:53:31,138 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2191:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:2544
2017-04-14 20:53:31,170 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2191:ZooKeeperServer@900] - Client attempting to establish new session at /127.0.0.1:2544
2017-04-14 20:53:31,248 [myid:1] - INFO [CommitProcessor:1:ZooKeeperServer@645] - Established session 0x15b6c2343f90011 with negotiated timeout 10000 for client /127.0.0.1:2544
2017-04-14 20:53:42,060 [myid:1] - INFO [CommitProcessor:1:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:2544 which had sessionid 0x15b6c2343f90011
客户端输出:
org.apache.zookeeper.proto.ConnectResponse@16de067[
protocolVersion=0
timeOut=10000
sessionId=97790715638644753
passwd={-18,75,33,46,-73,2,30,-80,-43,-55,-68,-125,-23,-87,6,72}
]
可以看出建立了一个新会话,会话id为:97790715638644753