问题来源:项目中出现顶号操作的时候,正常情况下被顶掉的连接应该收到一个 “同一账号登录,请退出重登” 的错误消息, 但是偶现客户端接收不到消息的情况(连接实际上已经被服务器干掉了,客户端就呆呆的,点啥也不动)。
解决思路——查日志,在各个怀疑的节点增加日志之后发现顶号 逻辑实际没有问题。只是 我们会通过心跳来 检测当前连接的有效性,也就是 说:
时刻1: 连接A --> login server --> ok
时刻2: 连接B --> login server , 此时全局token 已经变了,①即将给连接A 发 “同一账号登录,请退出重登” 的错误消息。ctx.writeAndFlush(msg)。
连接A --> send heart pkt , 发现自己连接中的token 和全局token不匹配,②关闭自己的连接–ctx.close()(这里也应该增加一个 发送错误消息的逻辑)。
如果先②后①就出现客户端收不到消息的现象了。
查看Netty 4代码发现
close 操作执行逻辑
io.netty.channel.AbstractChannel.AbstractUnsafe#close(io.netty.channel.ChannelPromise)
writeAndFlush() 操作逻辑
io.netty.channel.AbstractChannelHandlerContext#writeAndFlush(java.lang.Object, io.netty.channel.ChannelPromise)
一路跟进来又来到AbstractChannel这里了
io.netty.channel.AbstractChannel.AbstractUnsafe#write
flush()
io.netty.channel.AbstractChannel.AbstractUnsafe#flush
小错误又给我上了一课