第 8 章 连接生命周期与正确关闭
8.1 常见事件的意思
| 事件 | 可以先这样理解 |
|---|---|
channelRegistered |
Channel 注册到 EventLoop |
channelActive |
连接进入活动状态 |
channelRead / channelRead0 |
收到一条进入当前处理器的消息 |
channelReadComplete |
当前一轮读事件结束,不代表业务消息结束 |
channelInactive |
连接变为非活动状态 |
exceptionCaught |
处理传播过来的异常 |
握手、鉴权等上层状态不一定与 channelActive 相同。例如 TCP 已连接,不代表 TLS 握手成功,更不代表用户已登录。
8.2 为什么先发送,再在监听器里关闭
示例对 quit 的处理为:
ctx.writeAndFlush("再见\n")
.addListener(ChannelFutureListener.CLOSE);它表达“这次写操作完成后关闭”。如果先调 writeAndFlush 再立即调 close,就可能过早关闭,影响待发送的数据。即使监听器触发,也不能据此证明对方业务已消费这条消息。
write 是把消息交给出站处理过程,flush 请求把待写内容推进到底层。高吞吐场景可以批量 write 后再 flush;初学示例每次直接使用 writeAndFlush,便于观察。
8.3 断线不等于立即可见
拔网线、设备休眠、对端崩溃等情况下,本地不一定马上收到明确的关闭通知。应用要按业务要求设计空闲检测、请求超时、心跳和重连。
重连不是简单死循环:应设置退避、随机抖动、最大频率与退出条件;断线时已发送但未获应答的请求处于不确定状态。若要重试修改数据的操作,需要幂等键或去重机制。
小练习: channelReadComplete 能否当作“收到一条完整订单”的判断条件?