微信蓝牙协议栈是什么是什么,如何在我的APP中使用

微信客户端授权登录开始邀请第三方应用内测了,我们虽然是个创业团队,但很幸运的成为了该功能的早期内测用户,经过半年多的试用,积累了不少的经验和教训,分享出来,希望对大家有所帮助。 微信授权登录的优势有哪些?1. 数亿微信用户直接登录, 免去繁琐注册流程。2. 支持获取用户基本信息,免去用户填写个人资料的烦恼,并且内容真实可靠。 一个iOS应用使用微信授权登录的过程应该是怎样的?申请微信授权登录&微信sdk接入&多应用账号打通&提交AppStore审核&上线 为什么提交AppStore审核也列入了这个过程?因为这里坑最多,我们一开始缺乏经验,足足在这步浪费了差不多两个月的宝贵时间! 下面,我们就按照这个过程,逐一进行介绍。 第一步:申请微信授权登录 微信授权登录的申请条件?只要应用已经获得了微信支付的权限,就可以提交申请。 具体怎么申请,官方有很详细的介绍,这也不是本文的重点,所以就直接略过了。附上微信开放平台的地址:https://open./ 在这里要重点指出的是:1. 客户端的授权登录是在微信开放平台申请的。2. web端的授权登录除了要在微信开放平台申请外,还要申请微信公众平台的服务号并完成认证,获取高级接口的访问权限。修正:微信的伙伴们反馈了最新的进展,web端的授权登录现在可以不用公众号了。 第二步:微信sdk接入 如果你的申请被通过,会得到一个包含有微信授权登录的SDK包,这个包同时也包含了基础的分享功能。具体的接入方法,微信会在SDK包中提供详细的说明文档,按照文档进行接入即可。 在这里要重点指出的是:1. 授权成功后返回的OpenID仅仅是应用内唯一标识,同一用户在不同应用进行授权,返回的OpenID是不一样的!2. 即使是同一个应用,同一个用户在移动应用授权登录和在web应用授权登录,返回的OpenID也是不一样的! OpenID都不一样,那我的产品是一系列应用,想统一账号怎么办?别急,继续往下看,微信已经提供了解决方案的。 第三步:多应用打账号打通 如果你们的产品是一个系列应用,又或者同时有移动应用和web应用,那么按照微信的规定,每个应用都必须在开放平台进行登记和审核(需要绑定包名,所以不能多个应用使用同一个签名),这也就意味着这些应用每个都是独立的应用!前面说过,这样会导致这一系列应用当用户授权后,返回的OpenID都不一样,无法唯一标识用户!这时就需要使用UnionID机制来解决这个问题。 UnionID使用规则如下:1. 同一个授权用户,在同一个开放平台账号下的应用中进行授权,返回的UnionID是相同的。2. 同一个授权用户,在绑定到同一个开放平台账号下的公众账号进行授权,返回的UnionID是相同的。这下多应用账户打通的问题就彻底的解决了吧! 第四步:提交AppStore审核 本来不该写这个环节的,因为这个环节貌似跟微信授权登录没什么关系,但其实这里才是本文最最最重要的地方,这里真的是坑多且深啊,我们足足在这里耗了两个月左右... 当我们[第一次]满心欢喜的以国内少数几个(现在我怀疑就是第一个!)仅支持微信授权登录应用的姿态,把应用提交到AppStore审核两周后,得到了我们的第一个拒绝通过的审核理由:你们的微信登录按钮点了没反应! 微信登录按钮为什么会没反应?我们可是经过了充分的测试了呀!特别是微信授权登录流程,更是测的不能更细致了!最后我们发现,这个登录按钮如果想没反应,那一定要做一件事情:卸载微信!好吧,是我们的问题,作为一个创业团队,没有配专职的测试人员,测试经验不足,遗漏了这一步,让苹果大神您测出来了,我们认了! 我们立刻为微信登录按钮添加了微信是否安装的检测,如果检测到微信没有安装,那我们就弹出对一个提示框,提示用户要去下载微信,而且提示框还提供了直接跳到AppStore下载微信的按钮,我们甚至还贴心的添加了英文版的提示框(因为AppStore拒绝我们通过的理由中的截图是英文版的系统)。 这下我们信心满满的[第二次]向AppStore提交审核,差不多两周后得到了我们的第二个拒绝通过的审核理由:你们应用设置了太高的门槛,必须要安装微信才能登录和使用你们的应用!你们要么使用自己的用户授权认证系统,要么让你们目前的登录不需要安装微信就可以使用。 我们郁闷,我们不服,我们去申诉:我们使用微信授权登录是为了提供更好的,是为了避免用户输入个人资料的繁琐过程呀! 申诉结果在五天后反馈到了我们:我们仔细阅读了你们的申诉内容,但是还是认为你们应用设置了太高的门槛,必须要安装微信才能登录和使用你们的应用!你们要么使用自己的授权认证系统,要么让你们目前的登录不需要安装微信就可以使用。 好吧,我们屈服了,我们作为一个创业团队,无法让微信授权登录的sdk在未安装微信的时候,可以跳转到web页面进行授权,我们只好用了两天时间开发了基于手机号和验证码的注册登录系统,开始[第三次]向AppStroe提交审核。这次的审核用了一周多的时间,审核的速度是快起来了,可是还是悲剧了!理由甚至都没变:你们应用设置了太高的门槛,必须要安装微信才能登录和使用你们的应用!你们要么使用自己的用户授权认证系统,要么让你们目前的登录不需要安装微信就可以使用。 这次我们彻底愤怒了,增加了那么明显的手机号验证码授权登录界面啊,审核大哥你不可能没看到啊,居然还用同样的理由拒绝我们,太过分了吧!这次我们使用了更为强烈的措辞进行了申诉,申诉结果在提交后的第四天得到了反馈:我们注意到了你们已经提供了自己的用户授权认证系统,但是你们使用的微信授权登录设置了太高的门槛,必须要安装微信才能登录和使用你们的应用!你们要么使用自己的用户授权认证系统,要么让你们目前的登录不需要安装微信就可以使用。 当时我们都无语了,审核大哥你要不要做的这么绝啊!我们当时甚至萌生了要不索性把微信授权登录去掉,换成微博授权登录念头!最终,我们决定做最后一次尝试,就是应用在登录的时候,主动检测微信是否有安装,如果没有安装的话,直接把微信的授权登录按钮隐藏掉,只保留我们自己的注册登录功能!这是我们[第四次]向AppStore提交审核,心里剩下的只有忐忑......六天后,审核通过了!审核终于通过了!喜极而泣啊! 回想整个应用提交AppStore审核过程,耗时近乎两个月,从世界杯前硬生生被拖到世界杯彻底结束,我们的应用是个专注宵夜应用啊,世界杯过了,我们的推广难了n倍啊!希望大家看了我们的经历,能够吸取教训,不要重蹈我们的覆辙! 以上就是我们应用使用微信授权登录提交AppStore审核的过程。
24小时报不停
继印度后,小米将在希腊开设首个线下店
支付宝无现金模式升级停车场,识别车牌后抬杆就走
摩拜单车7月登陆日本,年内扩大至10个城市
联想控股战略入股东航物流,将持股25%
全球最赚钱10款手游中国占9席,腾讯5款游戏上榜
传特斯拉将在上海设厂,去年在华营收翻两番超10亿美元
女装品牌七格格宣布关店,京东回应:理解二选一,不容忍平台差价
受618大促业绩影响,京东和阿里巴巴股价纷纷大涨
联合办公空间倍格创业宣布完成A轮1800万美金融资
特朗普召见大批科技公司CEO:减少浪费和改进IT服务
京东送货机器人正式启用,造价相当一辆奥迪Q7
ofo小黄车新用户押金涨至199元,回应称正在构建新的信用体系
驿氪科技获DCM领投400万美金A轮融资
易鲜冷链获得数千万人民币天使融资
腾讯AI加速器复试开启,五大资源助力AI创业
Stager Live 完成数千万人民币A轮融资
易工程获得数千万元Pre-A轮融资
阿格斯获得3000万人民币A轮融资
咿啦看书获得5000万元人民币A轮融资
42章经完成640万元Pre-A轮融资 将涉足社群和FA业务
Nonolive直播平台获阿里、斗鱼及微影资本数千万美元融资
京东618全民年中购物节累计下单金额达1199亿元4639人阅读
微信硬件开发和物联网(31)
蓝牙开发(22)
蓝牙CC254x(11)
基于Ti CC2541 SDK自带的simpleBLEPeripheral工程实现微信蓝牙Airsync协议,同时支持微信串口透传和一般APP串口透传。相关源码和开发资料请阅读《》。 嵌入式企鹅圈以lib库(lib_wehat.lib)的形式提供微信蓝牙Airsync协议,这里介绍如何在simpleBLEPeripheral工程中添加lib_wehat.lib,并通过简单的修改即可实现微信串口透传功能。1.&&&& simpleBLEPeripheral工程添加微信库和包含微信profile头文件 1)在simpleBLEPeripheral.C中添加: #include&ble_wechat_profile.h& & & & & 2)工程添加lib_wehat.lib。2.&&&& 修改默认广播数据红色部分是蓝牙的MAC地址,第3步会自动更新。广播中需要说明支持微信airsync协议的UUID和设备的唯一MAC地址。static uint8advertData[] ={& 0x02, & GAP_ADTYPE_FLAGS,& DEFAULT_DISCOVERABLE_MODE |GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,& // service UUID--wechat service& 0x03,&&// length of this data& GAP_ADTYPE_16BIT_MORE,&&& &LO_UINT16( WECHAT_SERV_UUID ),&HI_UINT16( WECHAT_SERV_UUID ),& //self data& 0x11,& GAP_ADTYPE_MANUFACTURER_SPECIFIC,& 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};3.&&&& 根据实际的MAC地址配置广播数据即修改默认广播数据中红色标注的MAC地址信息。xDATA中的0x780E到0x7813存储MAC地址。在SimpleBLEPeripheral_Init函数中添加:advertData[19]= *((uint8*)0x7813);advertData[20]= *((uint8*)0x7812);advertData[21]= *((uint8*)0x7811);advertData[22]= *((uint8*)0x7810);advertData[23]= *((uint8*)0x780F);advertData[24]= *((uint8*)0x780E);GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof(advertData ), advertData );4.&&&& 添加微信Airsync profile服务在SimpleBLEPeripheral_Init函数中添加:WechatProfile_AddService(GATT_ALL_SERVICES);5.&&&& 初始化微信Airsync服务的各个特性值在SimpleBLEPeripheral_Init函数中添加:&& uint8charValueRead[WECHATPROFILE_CHAR_READ_LEN];&&&&&&& charValueRead[0] = *((uint8*)0x7813);&&& charValueRead[1] = *((uint8*)0x7812);&&& charValueRead[2] = *((uint8*)0x7811);&&& charValueRead[3] = *((uint8*)0x7810);&&& charValueRead[4] = *((uint8*)0x780F);&&& charValueRead[5] = *((uint8*)0x780E);&&& uint8charValueIndicate[WECHATPROFILE_CHAR_INDICATE_LEN] = {10,11,12,13,0};&&& uint8charValueWrite[WECHATPROFILE_CHAR_WRITE_LEN] = { 1, 2, 3, 4, 5 };//微信Airsync协议的READ characteristics 初始化,读MAC地址WechatProfile_SetParameter(WECHATPROFILE_CHAR_READ,WECHATPROFILE_CHAR_READ_LEN, charValueRead );//微信Airsync协议的Indicate characteristics 初始化,设备主动发送消息数据WechatProfile_SetParameter(WECHATPROFILE_CHAR_INDICATE,WECHATPROFILE_CHAR_INDICATE_LEN, charValueIndicate );//微信Airsync协议的write characteristics 初始化,设备被动接受写数据WechatProfile_SetParameter(WECHATPROFILE_CHAR_WRITE,WECHATPROFILE_CHAR_WRITE_LEN, charValueWrite );6.&&&& 初始化微信Airsync服务状态机在SimpleBLEPeripheral_Init函数的最后添加:wechat_init();7.&&&& SimpleBLEPeripheral_ProcessEvent应用事件处理函数中增加微信服务事件处理if ( events& SBP_START_AUTH_CONNECTION_EVT ) {&&&&&&&&&&&&& &&& //登录授权wechat_main_process(NULL);&&& return (events ^SBP_START_AUTH_CONNECTION_EVT);& }& & if ( events &SBP_START_INIT_CONNECTION_EVT ) {&&&&&&&&&&&& &&//初始化wechat_main_process(NULL);&&& return (events ^ SBP_START_INIT_CONNECTION_EVT);& &&&& }8.&&&& simpleBLEPeripheral_ProcessOSALMsg系统消息处理函数中增加APP手机蓝牙连接后订阅微信indicate服务的处理。caseGATT_MSG_EVENT:&&&&& if ( ((gattMsgEvent_t *)pMsg)-&method== ATT_HANDLE_VALUE_CFM )&&&&&&& {&&&&&&&&&&& on_indicate_comfirm();&&&&&&&&&& &&&&&&& }&&&&&9.&&&& peripheralStateNotificationCB连接状态变化时重置微信服务状态机GAPROLE_CONNECTED连接时调用wechat_init();GAPROLE_WAITING断开连接时调用wechat_init();10.& simpleProfileChangeCB特性值变化(客户端写操作)时的回调case WECHATPROFILE_CHAR_WRITE:&&&&&WechatProfile_GetParameter(WECHATPROFILE_CHAR_WRITE, newChar5Value );&&&&& on_write(newChar5Value, 20); &&&&&此时读到的数据是经过protobuf打包的数据格式,在on_write中会解包,并会回调以下接口:&&&&&&& void on_write_user_hook(unsigned char*str, unsigned char len);&&&&&&& 该接口由用户实现,str即是客户端透传的数据,len是长度。可以选择输出到串口。str的数据格式是微信官方后台demo(rose_blue)定义的应用自定义数据格式。11.& 设备主动发消息(indicate)的接口int32wechat_indicate_handler(void *dataBuf, uint8 len);该接口中会将用户的dataBuf以微信官方后台demo(发送515获得,roseblue_anichips.zip)定义的应用自定义数据格式进行protobuf打包,并发送给手机微信,最终到达厂商后台。12.& 用户如何基于微信Airsync协议定制自己的应用1) 微信官方后台demo定义的应用自定义数据格式有头部HEAD和包体body。用户可以自行定义body的数据格式,并修改后台服务和蓝牙设备端的处理过程。2) 设备主动发送数据使用第11步的wechat_indicate_handler接口。3) 设备收到数据会回调第10步的on_write_user_hook接口,用户的处理代码添加到该接口即可。 目前微信串口透传和APP透传的设备端源码工程、微信后台源码工程、android APK均已经提供。& & & & 更多嵌入式和物联网原创技术分享敬请关注微信公众号:嵌入式企鹅圈
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:418909次
积分:5520
积分:5520
排名:第4460名
原创:124篇
转载:10篇
评论:220条
百分百原创,每周两篇,阿里、魅族、nvidia、炬力、拓尔思等顶级企业资深工程师分享----嵌入式、Linux、物联网、GPU、Android、自动驾驶等技术,欢迎扫码关注!
文章:14篇
阅读:32409
文章:40篇
阅读:198714
文章:10篇
阅读:21833
(1)(3)(5)(1)(2)(2)(2)(4)(2)(2)(1)(7)(9)(8)(4)(5)(5)(3)(5)(5)(5)(3)(3)(3)(3)(3)(1)(13)(2)(2)(1)(6)(13)(1)说明:微信客户端协议本身二进制协议而且加密,要分析协议具体编码格式是比较困难的。我也只是简单抓包分析主要业务的实现流程,记录下来用于参考学习,并不涉及协议的编码格式,并不是破解协议。
  道听途说,加上上面参考中都是提到微信使用Sync协议。去年项目中做过参考Microsoft Exchange ActiveSync 协议来优化消息协议的方案,虽经过长时间讨论定稿,但由于一些原因最终没有实现;也从中深知Sync并不是表面上那么简单、那么好用。
  Sync 有啥问题呢?
  1. SyncKey 生成维护成本
    SyncKey 在ActiveSync中为字符串,客户端不需要解析,但服务端实现要用数字自增,需要强一致性,且不能回退。
  2. 消息的订阅模式 采用类似Zookeeper的One time triggler 还是每条消息都推送一条通知能
    One time trigger能够避免并发通知时,获取消息时重复问题,但增加了交互成本,和客户端实现复杂性。
  3. 自己发的消息,SyncKey怎么获取
    尤其要支持多端同步发消息,保证消息同步;也只好消息发完在给自己同步一遍(自己设备发的可以不带消息体)
  4. 消息推送延时加重
    Sync 消息体获取方式:Notify - Ack - get - Mssage, 也就是至少第四个应用包才能返回消息,在移动网络下成本很高。文中提到消息通过单独https请求,那么延时更为严重了(嗯,实测新版本并非如此)。
手机客户端不再Sync协议
抓包分析版本:Android 微信6.0, 抓包分析可参考:
在wifi、gprs网络状况下都相同,客户端会依次尝试使用80、 端口连接服务器;消息发送、接收都使用长连接进行.
协议格式:
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,将随后文章分析。
& & &1. 服务器推送消息, Operation = 7a, &Body 中携带消息内容
    抓包分析时,通过改变消息体大小,可能到接收方第一个包length 也会随之变化,可确认消息是push的。
& & &2. 发起客户端单向请求,即消息的应答Ack
& & &未分析,一般来说像whatsapp那样,使用 hash(密码/OTP + 长连接第一个请求获取RandomCode) 做RC4 的密钥
现在版本的微信消息推送,并非Sync方式,而是推送+ack方式;
从他们协议设计来看,应该最开始用的是Notify + Sync Req + Sync Rsp 方式,因为协议上是不支持服务器发起请求的;
现在改成 Sync 消息+ 单向 Ack Req 的push方式,虽然协议上怪异, 相比Sync 消息接收会更加及时。从以前看到的文章都是说用的Sync协议,应该是是后期版本做了修改,push方式更为高效、而且通过顺序的SyncKey也能够修复丢失的消息。
下面一个通知包示例:
4 byte: 265 PacketLen
2 byte: 16 & Head Length
2 byte: 1 & & Protocol Version
4 byte: 7a & Operation
4 byte: 0 & SeqId 这是一个通知性消息
4 byte: unknow header
  web微信客户端使用比较标准的Sync协议,Sync协议也比较适合web长轮询模型。
  移动客户端模式下,协议是二进制的而且有加密,很难分析;微信侧重手机端,web端主体协议应该保持与移动端一致,可通过web端推测整体协议实现,json也比较好分析。
  接收一条消息后SyncKey变化: 
  synckey:1____1_|656  synckey:1____1_|656
  可以看出:
  -&Synckey 有多个,应该是应对不同业务,其中2为为所有个人消息、讨论组消息,其他可能是联系人、朋友圈、订阅号等,201 为当前时间戳。
  - SyncKey 的值为数字自增,不是从0开始,应该有个固定的初始值。  
  - 发消息时,发完需要自己给再自己同步回一下SyncKey。
- 下面是一条消息增量同步结构,一堆要同步字段+是否修改FlagMask,同步协议变得很简洁。
"BaseResponse": {
"ErrMsg": ""
"AddMsgCount": 1,
"AddMsgList": [{
"MsgId": ,
"FromUserName": "@sssss",
"ToUserName": "@ssssssss2",
"MsgType": 1,
"Content": "捶地笑&&",
"Status": 3,
"ImgStatus": 1,
"CreateTime": ,
"VoiceLength": 0,
"PlayLength": 0,
"FileName": "",
"FileSize": "",
"MediaId": "",
"Url": "",
"AppMsgType": 0,
"StatusNotifyCode": 0,
"StatusNotifyUserName": "",
"RecommendInfo": {
"UserName": "",
"NickName": "",
"QQNum": 0,
"Province": "",
"City": "",
"Content": "",
"Signature": "",
"Alias": "",
"Scene": 0,
"VerifyFlag": 0,
"AttrStatus": 0,
"Ticket": "",
"OpCode": 0
"ForwardFlag": 0,
"AppInfo": {
"AppID": "",
"HasProductId": 0,
"Ticket": ""
"ModContactCount": 0,
"ModContactList": [],
"DelContactCount": 0,
"DelContactList": [],
"ModChatRoomMemberCount": 0,
"ModChatRoomMemberList": [],
"Profile": {
"BitFlag": 0,
"UserName": {
"Buff": ""
"NickName": {
"Buff": ""
"BindUin": 0,
"BindEmail": {
"Buff": ""
"BindMobile": {
"Buff": ""
"Status": 0,
"PersonalCard": 0,
"Alias": "",
"HeadImgUpdateFlag": 0,
"HeadImgUrl": "",
"Signature": ""
"ContinueFlag": 0,
"SyncKey": {
"Count": 6,
"List": [{
"Key": 11,
"Key": 201,
"Key": 1000,
"SKey": ""
阅读(...) 评论()

我要回帖

更多关于 蓝牙协议是什么 的文章

 

随机推荐