如下图所示,为redis 客户端连接服务器完整的流程。
1.首先在redis sever 启动的时候,会把AE_READABLE事件和acceptTcpHandler方法绑定,向eventLoop注册。
1 | if (server.ipfd > 0 && aeCreateFileEvent(server.el, server.ipfd, AE_READABLE, acceptTcpHandler, NULL) == AE_ERR) |
2.当client连接server时,会触发redis sever的AE_READABLE事件为就绪状态。
3.当AE_READABLE事件为就绪状态时,会在aeMain中对其进行处理,并执行绑定的acceptTcpHandler方法。在acceptTcpHandler方法中,会创建client实例,并将client的AE_READABLE事件和readQueryFromClient方法绑定,向eventLoop注册。
1 | redisClient *createClient(int fd) { |
4.client向server想要执行的命令,触发client的AE_READABLE事件变为就绪状态。
5.同理,在aeMain中对AE_READABLE变为就绪状态的事件进行处理。执行绑定的readQueryFromClient方法,并执行相应的命令。在命令执行过后准备发送结果给client之前,会把client的AE_WRITEABLE事件和sendReplyToClient方法绑定, 向eventLoop注册,同时发送命令,触发AE_WRITEABLE事件。
1 | int prepareClientToWrite(redisClient *c) { |
6.在aeMain中对AE_WRITEABLE的事件进行处理,执行绑定的sendReplyToClient方法,把命令发送给client,同时删除向eventLoop注册的AE_WRITEABLE事件。
1 | void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { |