B broker把心跳包转给专门处理心跳逻辑的msg chat server[以下称为heartbeat server];
C heartbeat server到Router中更新client的在线状态以及登录的broker的id和最新登录时间;
D heartbeat server到Counter服务器循环查询每个channel的最新消息id,如果客户端上报的id与这个id不等,就发送一条msg通知msg chat server,msg = {uin, channel name, client newest msg id of channel};
E msg chat server收到这条消息后,重新启动消息下发逻辑,到msg queue中取出所有的大于{client newest msg id of channel}的id列表;
F msg chat server依据list中的id到消息存储服务器中依次取出每个msg[取不到也就表示这个消息因为超时而被消息存储服务器删除了];
G msg chat server把这些消息作为"未读消息"下发给客户端;
H heartbeat server根据Router存储的客户端的最近三次的登录时间,调整session的心跳时间间隔,作为心跳回包的一部分参数值给客户端下发heartbeat ack包,其他数据包括其所在的每个channel的最新消息的msg id;
I heartbeat server定时地到Router中检查所有客户端的最新登录时间,如果超过其session有效时间,就把其state置为“离线”,并删除其登录服务id等数据;
上面提到的一个词:newest channel id 或者 client newest msg id of channel,其意思就是消息接收者所在的channel的所拥有的本地消息的最新id。一般地,如果server端的Counter能够稳定地提供服务,channel中的msg id应该是连续的,如果客户端检测到msg id不连续,可以把不连续处的id作为newest channel id,要求server端再把这个msg id以后的消息重发下来,这就要求client有消息去重判断的功能。