zoukankan      html  css  js  c++  java
  • [微信协议分析] 多点登陆

    声明:微信客户端协议是二进制协议而且加密,难以分析协议具体编码格式,我不做逆向工程。只是简单抓包分析业务的实现流程,在这里记录下来用于参考学习,并不是破解协议。

      IM产品的多点登陆逻辑特别复杂,很难做到很好的用户体验,就像新版mac handoff 功能也不少人在喷。

      微信最开始并不支持多点登陆,后来陆续增加的Web版、Mac版,但并不是完整意义的客户端,要说只是辅助输入。

      微信允许: 一个移动端(下面称之为主客户端) + 一个web/mac 同时在线(下面称之为从客户端),web/mac 只能接收在线消息、发消息,不记录消息历史。这样多点逻辑就变得相对简单很多了。

      存储

      服务器不用保存完整消息历史,通过客户端对push消息的ack保证消息送达,协议保证消息至少一次推送到主客户端,然后消息即可删除;服务器只存储未下发到主客户端的消息。

      多点时:主客户端依然采用Push推送消息(只是应该会保留一小段时间消息记录等待从Sync),从客户端Sync消息;如果主不在线,消息记录不会删除,等主重新连上下载离线消息。

      服务器不存储消息历史,一个是安全,再者节省硬件成本,大量短消息的存储和读取成本是非常高的,因为基本都是随机IO。whatapp 用500台机器,支撑1亿在线,虽然有100w/s 消息,只离线消息存储量是很少的。

     未读数同步

       这个很好解决,如果客户端知道自己处于多端在线情况下时,进入会话时,需要告诉服务器消息已读。消息已读也保存为一条消息,再通过Sync协议,同步到另外的客户端。web 微信会调用webwxstatusnotify 同步未读。

      未读变化也当成一条消息存储,且只在多端情况下存在,单点在线时未读数由客户端维护。

      删除消息

      不管是否多点在线任何删除消息操作都会同步到服务器,避免删除的消息下次有不小心同步回来了,服务器可能及时删除、也可能长期保存,客户端每次上报就没错了。

      移动客户端消息删除不会同步到 web版。

     自己同步自己

       每个操作(发消息、清未读等),应答后,因为SyncKey 变化了,Sync协议上会产生一个空的Sync操作用于更新SyncKey。

       为啥不通过应答更新SyncKey?  并发情况直接更新会造成丢消息问题,也保证协议的统一性。

      对于主客户端:

      - 单点在线时发消息,并不会同送空的SyncKey,SyncKey应该是通过应答防护,节省同步流量。怎么防止丢消息呢?

       猜想是这样: 请求时带上SyncKey(local), 服务器在inc SyncKey得到SyncKey(current) == SyncKey(local) 时,直接返回SyncKey(current),否则返回Sync(local) 并推送New SyncKey Notify。因为此时确保客户端没有未收消息,坏情况应答比新消息慢,也不会有啥问题。

        - 多点在线时,发消息和从客户端一样,也会自己同步自己

     

  • 相关阅读:
    ans Single VIP LLB and SLB config
    Kindle支持文档类型
    RFC2544测试指标
    C#中equal与==的区别
    COGS 144. [USACO Dec07] 魅力手镯【01背包复习】
    我的第六个网页制作:table标签
    我的第五个网页制作:pre、html转义、abbr标签的使用
    我的第四个网页制作:列表标签
    我的第三个网页制作:b、i、s、u、sub、sup标签的使用
    我的第二个网页制作:p,hn,br标签的使用
  • 原文地址:https://www.cnblogs.com/lulu/p/4199770.html
Copyright © 2011-2022 走看看