1. http如何像tcp一样实时的收消息?
长轮询实际怎么玩
1)消息连接:webim和webserver之间建立一条http连接,专门用作消息通道,这条连接叫http消息连接
2)消息连接的4大特性
a. 没有消息到达的时候,这个http消息连接将被夯住,不返回,由于http是短连接,这个http消息连接最多被夯住90秒,就会被断开(这是浏览器或者webserver的行为)
b. 在1)的情况下,如果http消息连接被断开,立马再发起一个http消息连接【见下图中的步骤1、2】
c. 在1)和2)的配合下,浏览器与webserver之间将永远有一条消息连接在(极限情况下会出现4)),每次收到消息时,这个消息连接就能及时将消息带回浏览器页面,并且在返回后,会立马再发起一个http消息连接
d. 如果消息到达时,上一个http消息连接正在返回,没有http消息连接可用(理论上http消息连接的返回是瞬时的,没有连接可用出现的概率极小),则将消息暂存入消息池中,下一个消息连接到达后(上一个
消息连接返回后,根据2)和3)会立马返回新的消息连接,无等待时间),将消息带回,并又立刻返回生成新的消息连接
结论:
webim通过http长轮询可以保证消息的绝对实时性。这种实时性的保证不是通过增加轮询频率来保证的,而是通过夯住http消息连接来保证的,在大部分时间没有实时消息的情况下,这个http消息连接对于webserver的
请求压力是90秒1次,能够大大节省了web服务器资源。
2. 微信为什么不丢消息?
1)im系统是通过超时、重传、确认、去重的机制来保证消息的可靠投递,不丢不重
2)一个“你好”的发送,包含上半场msg:R/A/N与下半场ack:R/A/N的6个报文
3)im系统难以做到系统层面的不丢不重,只能做到业务层面的不丢不重
3. 微信为啥不丢“离线消息”?
1)问题:接收方不在线时,消息发送的流程是怎么样的?
服务器将消息存储到DB中
2)“离线消息”的可达性可能比大家想象的要复杂,常见的优化有:
(1)对于同一个用户B,一次性拉取所有用户发给ta的离线消息,再在客户端本地进行发送方分析,相比按照发送方一个个进行消息拉取,能大大减少服务器交互次数
(2)分页拉取,先拉取计数再按需拉取,是无线端的常见优化
(3)应用层的ACK,应用层的去重,才能保证离线消息的不丢不重
(4)下一页的拉取,同时作为上一页的ACK,能够极大减少与服务器的交互次数
原文地址:https://www.cnblogs.com/Jtianlin/p/8969903.html