Connection建立连接,就是tcp的三次握手了,mysql协议中,当连接建立后,mysql数据库则发送HandshakePacket报文,向jdbc提供数据库版本号等信息,jdbc向mysql提供url用户名密码等进行身份认证。
NIOAcceptor创建一个FrontendConnection后,会将FrontendConnection注册到NIOReactor中,
/**
* [简要描述]:</br>
* [详细描述]:当连接建立完毕后,从reactorPool 中获得一个 NIOReactor,然后把连接传递到 NIOReactor,然后后续的 Read 和 Write 事件就交给NIOReactor 处理了。</br>
*/
private void accept() {
SocketChannel channel = null;
try {
channel = serverChannel.accept();
channel.configureBlocking(false);
FrontendConnection c = factory.make(channel);
c.setAccepted(true);
c.setId(ID_GENERATOR.getId());
NIOProcessor processor = (NIOProcessor) IsolationServer.getInstance()
.nextProcessor();
c.setProcessor(processor);
NIOReactor reactor = reactorPool.getNextReactor();
reactor.postRegister(c);
} catch (Exception e) {
LOGGER.warn(getName(), e);
closeChannel(channel);
}
}
NIOReactor监听channel读事件,并调用AbstractConnection的register方法,FrontendConnection重写了AbstractConnection的register方法,在此方法中,new一个HandshakePacket对象,并把握手报文发送出去。而后监听读事件,等jdbc方面的反馈。
if(useHandshakeV10) {
HandshakeV10Packet hs = new HandshakeV10Packet();
hs.packetId = 0;
hs.protocolVersion = Versions.PROTOCOL_VERSION;
hs.serverVersion = Versions.SERVER_VERSION;
hs.threadId = id;
hs.seed = rand1;
hs.serverCapabilities = getServerCapabilities();
hs.serverCharsetIndex = (byte) (charsetIndex & 0xff);
hs.serverStatus = 2;
hs.restOfScrambleBuff = rand2;
hs.write(this);
} else {
HandshakePacket hs = new HandshakePacket();
hs.packetId = 0;
hs.protocolVersion = Versions.PROTOCOL_VERSION;
hs.serverVersion = Versions.SERVER_VERSION;
hs.threadId = id;
hs.seed = rand1;
hs.serverCapabilities = getServerCapabilities();
hs.serverCharsetIndex = (byte) (charsetIndex & 0xff);
hs.serverStatus = 2;
hs.restOfScrambleBuff = rand2;
hs.write(this);
}