首页 存档 技术 查看内容

微信通讯协议的学习

2018-3-30 13:00 |来自: 互联网 1367 0

摘要: 架构师(JiaGouX)我们都是架构师! 微信协议概览 微信传输协议,官方公布甚少,在微信技术总监所透漏PPT《微信之道至简》文档中,有所体现。 微信从2011年1月发布以来,在一年之内实现了上亿用户,千万级在线, ...

架构师(JiaGouX)
我们都是架构师!


微信协议概览

微信传输协议,官方公布甚少,在微信技术总监所透漏PPT《微信之道至简》文档中,有所体现。


微信从2011年1月发布以来,在一年之内实现了上亿用户,千万级在线,在苹果中国区AppStore月下载量排行第一。腾讯把微信的成功总结为“三位一体”,即产品的精准,项目的敏捷,以及技术的支撑。敏捷就是试错法,用最快的迭代速度不断追求卓越。敏捷是一种态度,允许发布前十分钟的变更,并给予产品决策以最大的自由度。


微信使用的同步协议叫做SYNC,参考了微软的ActiveSync YNchronous ommunication:同步通信。没有数据发送时,传输线处于MARK状态。为了表示数据传输的开始,发送方先发送一个或两个特殊字符,该字符称为同步字符。当发送方和接收方达到同步后,就可以一个字符接一个字符地发送一大块数据,而不再需要用起始位和停止位了,这样可以明显地提高数据的传输速率。采用同步方式传送数据时,在发送过程中,收发双方还必须用一个时钟进行协调,用于确定串行传输中每一位的位置。接收数据时,接收方可利用同步字符将内部时钟与发送方保持同步,然后将同步字符后面的数据逐位移入,并转换成并行格式,供CPU读取,直至收到结束符为止。用一个Key来实现状态同步。这样一种协议在后台实现上比业界通用方案要复杂许多,但是能把客户端的实现大大简化,同时在很大程度上能够满足iPhone,安卓,塞班等多个操作系统的不同需求。


微信秉承“重后台轻客户端”的思路,因为客户端安装在用户手机上,变更成本很高;而后台则可以实现迅速的变更,在不发新版本的情况下实现新功能。以下是一个例子:微信的最初版本是不支持群聊的,第二个版本支持了群聊,但第一版客户端仍然可以在后台的变更处理之下参与群聊,只是不能够发起群聊而已。


其服务器端目前获知的几部分分别是三网专用网关服务器、登陆服务器组、负载均衡服务器组,主动推送服务器组、后台数据转换服务器组、存储阵列等几部分。由于目前没有任何能够直接从客户端保存至服务器端的功能,推测其服务方并没有用于数据记录的数据库服务器,而是在登陆服务器组中集成了用户数据库,用来记录用户授权。


因张小龙做邮箱Foxmail起家,继而又做了QQ Mail等,QQ Mail是国内第一个支持Exchange ActiveSync协议的免费邮箱,基于其从业背景,微信从一开始就采取基于ActiveSync的修改版状态同步协议Sync,也就再自然不过了。一句话:增量式、按序、可靠的状态同步传输的微信协议。


Microsoft Exchange Active Sync协议

Microsoft Exchange Active Sync协议,简称EAS,分为folderrsync(同步文件夹目录,即邮箱内有哪几个文件夹)和sync(每个文件夹内有哪些文档)两部分。


某网友总结的协议一次回话大致示范:


  • Client: synckey=0 //第一次key为0

  • Server: newsynckey=1235434 //第一次返回新key

  • Client: synckey=1235434 //使用新key查询

  • Server: newsynckey=1647645,data=*****//第一次查询,得到新key和数据

  • Client: synckey=1647645

  • Server: newsynckey=5637535,data=null //第二次查询,无新消息

  • Client: synckey=5637535

  • Server: newsynckey=8654542, data=****//第三次查询,增量同步


大致交换简图如下:

如何获取新数据呢:


  • 服务器端通知,客户端获取

  • 客户端携带最新的SyncKey,发起数据请求

  • 服务器端生成最新的SyncKey连同最新数据发送给客户端

  • 基于版本号机制同步协议,可确保数据增量、有序传输

  • SyncKey,由服务器端序列号生成器生成,一旦有新消息产生,将会产生最新的SyncKey。类似于版本号


服务器端通知有状态更新,客户端主动获取自从上次更新之后有变动的状态数据,增量式,顺序式。


微信的协议

为保证稳定,微信用了长链接和短链接相结合,微信划分了http模式(short链接)和 tcp 模式(long 链接),分别应对状态协议和数据传输协议


  • weixin.qq.com dns check (112.64.237.188 112.64.200.218)

  • weixin.qq.com dns check ( 112.64.237.186 112.64.200.240)


1)short.weixin.qq.com

是HTTP协议扩展,运行8080 端口,http body为二进制(protobuf)。主要用途(接口):


  • 用户登录验证;

  • 好友关系(获取,添加);

  • 消息sync (newsync),自有sync机制;

  • 获取用户图像;

  • 用户注销;

  • 行为日志上报。

  • 朋友圈发表刷新


2)long.weixin.qq.com

tcp长连接,端口为8080,类似微软activesync的二进制协议。主要用途(接口):


  • 接受/发送文本消息;

  • 接受/发送语音;

  • 接受/发送图片;

  • 接受/发送视频文件等。


所有上面请求都是基于tcp长连接。在发送图片和视频文件等时,分为两个请求;第一个请求是缩略图的方式,第二个请求是全数据的方式。


3)数据报文方面

  • 增量上传策略:每次8k左右大小数据上传,服务器确认;在继续传输。

  • 图片上传:先传缩略图,传文本消息,再传具体文件

  • 下载:先下载缩略图, 在下载原图,下载的时候,全部一次推送。


Sync 同样存在一些问题:


  • SyncKey 生成维护成本:SyncKey 在ActiveSync中为字符串,客户端不需要解析,但服务端实现要用数字自增,需要强一致性,且不能回退。

  • 消息的订阅模式:采用类似Zookeeper的One time triggler 还是每条消息都推送一条通知能,ne time trigger能够避免并发通知时,获取消息时重复问题,但增加了交互成本,和客户端实现复杂性。

  • 自己发的消息,SyncKey怎么获取,其要支持多端同步发消息,保证消息同步;也只好消息发完在给自己同步一遍(自己设备发的可以不带消息体)

  • 消息推送延时加重:Sync 消息体获取方式:Notify Ack get Mssage, 也就是至少第四个应用包才能返回消息,在移动网络下成本很高。


手机客户端不再Sync协议

抓包分析版本:wifi、gprs网络状况下都相同,客户端会依次尝试使用80、8080、443 端口连接服务器;消息发送、接收都使用长连接进行.


协议格式:


  • 4byte Packet Len(包含4字节本身)

  • 2byte Head Len(包含2字节本身) 2byte Version(1) 4byte Operation 4byte SeqId ….

  • (Packet Len Head Len) Body


协议交互方式:


  • 客户端请求(一应一答,通过seqid匹配):seqid = 1 开始,依次递增,服务器回复相同的seqid 作为应答

  • 服务器推送通知(单向):seqid = 0,Operation = 7a, 客户端不需要应答


主要业务:


  • -心跳包:发起客户端请求,Operation = 0c,长度为16字节,算是最小的包

  • -发消息:发起客户端请求,Operation = ed;单点在线时发完消息后,应答携带SyncKey,不再同步,多点在线时,通过通知同步SyncKey。

  • -收消息:服务器推送消息,Operation = 7a, Body 中携带消息内容,抓包分析时,通过改变消息体大小,可能到接收方第一个包length 也会随之变化,可确认消息是push的。发起客户端单向请求,即消息的应答Ack。

  • -加密:未分析,一般来说像whatsapp那样,使用 hash(密码/OTP 长连接第一个请求获取RandomCode) 做RC4 的密钥


APP抓包数据

1)初始连接记录

简单记录微信启动之后请求:


  • 11:20:35 dns查询weixin.qq.com 返回一组IP地址

  • 11:20:35 DNS查询 weixin.qq.com 返回一组IP地址,本次通信中,微信使用了最后一个IP作为TCP长连接的连接地址。

  • 11:20:35 http://dns.weixin.qq.com/cgi-bin/micromsg-bin/newgetdns?uin=0

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部