最新要闻
- 岳阳楼下诵经典|全球今日讯
- 当前观察:硬盘预读参数变化分析
- 继烧烤后淄博代购也火了:网友都很想去
- “五一”假期高速免费五天!提前出发的过省界收费站时注意时间 环球快播报
- 今日讯!五一这些景点门票已约满:游客注意别跑空
- 3200RPM超高转速 满速运转还不抖!酷冷至尊莫比乌斯120 OC风扇评测 环球报资讯
- 科幻工业风!红魔电竞显示器银翼版来了:极窄边框设计 热点评
- 贵阳市档案馆通过全国示范数字档案馆测试
- 兴齐眼药去年四季度起利润急降:“近视神药”网售被禁影响显现,正式上市时市场恐已成红海
- 7项技术行业唯一!vivo X Fold2今日首销:8999元起
- 五一档票房第一!王一博电影《长空之王》今日上映:歼-20真机硬核亮相_世界热头条
- 热议:四川瓦屋山首次发现猛禽之王:自然界顶级掠食者 海拔4000米以上活动
- 60架C919和40架ARJ21!海航豪购100架国产飞机 环球微头条
- 小鹏G6创意视频被指“侮辱科学家” 创作者发声:绝非侮辱而是致敬
- 证监会:下月公布虚拟交易平台发牌框架
- 一季度新接船舶订单量同比增53%(新数据 新看点) 环球看热讯
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
IM开发干货分享:IM客户端不同版本兼容运行的技术思路和实践总结
本文由巩鹏军分享,原题“IM兼容性基建”,本文有修订。
1、引言
一个成熟的IM成品,在运营过程中随着时间的推移,会发布不同的版本,但为了用户体验并不能强制要求用户必须升级到最新版本,而服务端此时已经是最新版本了,所以为了让这些不同客户端版本的用户都能正常使用(尤其IM这种产品,不同版本可能通信协议都会有变动,这就更要命了),则必须要针对不同客户端版本的兼容处理。
本文将基于笔者的IM产品开发和运营实践,为你分享如何实现不同APP客户端版本与服务端通信的兼容性处理方案。
(资料图片仅供参考)
学习交流:
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK(备用地址点此)
(本文已同步发布于:http://www.52im.net/thread-4202-1-1.html)
2、关于作者
巩鹏军:专注移动开发十多年,热爱即时通讯技术。个人微信公众号:“巩鹏军”。
作者在即时通讯网分享的另一篇《知识科普:IM聊天应用是如何将消息发送给对方的?(非技术篇)》,感兴趣的读者也可以看看。
3、一个App时怎么办?
提示:“一个App”指的是同一个IM服务端,只服务于一个特定的IM产品。
首先想到的就是直接使用App版本号判断新老版本并进行兼容处理。
如下图所示:
一般来说,不同的IM客户端(如iOS、Android、Windows、Mac)都是同步迭代,多端发版时间一致,App版本号也一样。
所以用跨多端的App版本号可以很容易地让服务端只用写一遍判断和兼容逻辑。
示例:假设从V2.1.0开始应用红包消息,那么判断客户端是否支持红包的逻辑就很简单。
伪代码如下:
booleanisSupportRedEnvelop(String appVersion) {
returngte(appVersion, "2.1.0");
}
附:版本号比对逻辑(未充分考虑异常情况):
List
toNums(String version) { Matcher matcher = Pattern
.compile("/[0-9]+\\.[0-9]+\\.[0-9]+")
.matcher(version);
String versionString = matcher.find()
? matcher.group(0).substring(1)
: "1.0.0";
List
verNums = Arrays .stream(versionString.split("\\."))
.map(Integer::valueOf)
.collect(Collectors.toList());
returnverNums;
}
booleangte(String version, String target) {
List
appVerNums = toNums(version); Integer appMajor = appVerNums.get(0);
Integer appMinor = appVerNums.get(1);
Integer appPatch = appVerNums.get(2);
List
targetNums = toNums(target); Integer targetMajor = targetNums.get(0);
Integer targetMinor = targetNums.get(1);
Integer targetPatch = targetNums.get(2);
return(appMajor >= targetMajor) ||
(appMinor >= targetMinor) ||
(appPatch >= targetPatch);
}
4、多个App时怎么办?
4.1概述
提示:“多个App”指的是同一个IM服务端,可能作为通用服务,作为多个不同APP产品中的聊天模块使用的场景。
只有一个App时肯定是比较简单的。但现实情况是一套IM系统通常会用于多个业务场景,这是很普遍的现象。业界的知名IM产品,比如钉钉、飞书、企业微信、美团大象等都是这样。
底层逻辑大概是:IM系统比较复杂,功能繁多而且难以实现、更难以稳定,所以一个IM团队维护一套IM系统,然后应用在多个业务场景就是最具性价比的选择了。
4.2使用App版本
每个业务场景都会有自己的客户端App,每个App都有自己的版本号,那么根据App版本号判断新老版本的逻辑就不适用了(如下图所示)。
一个App时可以这样做兼容性判断:
booleanisSupportRedEnvelop(String appVersion) {
returngte(appVersion, "2.1.0");
}
多个App时的兼容性判断:
booleanisSupportRedEnvelop(String version) {
return
(app.equals("App1")&>e(version,"2.1.0"))||
(app.equals("App2")&>e(version,"2.2.3"))||
(app.equals("App3")&>e(version,"6.1"));
}
4.3使用App版本号的麻烦
随着App的增多,需要的判断也越多,这会很麻烦,也很容易出错。
每个App推出新版本后,用户不可能瞬间就升级到最新版本,根据经验,每个App往往都会同时存在十个以上的不同版本。
这就会形成如下图所示的局面:
5、多个App时,可将IM能力提炼为一套公用代码
多个App时的问题总结起来就是:一套服务端代码如何适应集成了不同IM能力的不同App客户端?
我们来具体举例分析一下,假设一个IM团队维护的IM相关的客户端模块有IM Client SDK、联系人、长连接、朋友圈等四个模块(如下图所示)。
如上图所示:
- 1)App 1:集成了全部四个模块;
- 2)App 2:只集成了三个模块;
- 3)App 3:只集成了三个模块。
因为三个App面向的客户群不同,发版节奏不同,所以各自集成的IM的能力也不同。
比如下面这样:
- 1)App 1:面向内部员工办公沟通使用的App 1需要功能丰富,对于稳定性和Bug有一定的包容性,也容易沟通和修复再发版;
- 2)App 2:面向客服场景,用于企业的客服专员和企业的C端用户沟通解决客诉问题,对于稳定性要求高,C端用户升级率不好控制,发版节奏慢,最快只能和主业务App一致;
- 3)App 3:面向企业和B端供应商,比如美团和美团上的商户,京东和京东平台上的第三方商家,对于稳定性要求也比较高,B端商家的升级率好控制一点,发版节奏也可以快一些。
从上图可以看出,因为IM核心能力是同一个团队维护,所以Core包含的多个模块的代码必然是只有一套源代码。不同App只是Core集成打包出来的产物,或者说不同App只是Core外面套了不同的壳而已,只要Core一样,则App的IM能力就一样(这就是本节标题所述的“多个App时,可将IM能力提炼为一套公用的代码”这个意思)。
6、给每个App中使用的公用代码(Core)一个版本号
如上节所述,我们将IM能力提炼为一套公用代码(以下内容简称“Core”)。
那么,我们能不能给Core一个版本标识呢?
答案是肯定的:
站在App的角度,每个App相当于打上了Core版本标签:
7、如何正确地解读Core版呢?
7.1抛开App看Core版本
如果不看App版本,只看Core版本标签:
7.2从一套服务端代码看Core版本
同一个IM团队,其IM Servers必然也是同一套代码集,不考虑部署的区别。
那么上图逻辑上等价于下图:
7.3使用Core版本的兼容性判断
站在Core的视角,多个App就像单个App类似,只是使用的版本标识不同。
具体如下:
- 1)单个App时,IM服务端要区分不同App版本;
- 2)多个App时,IM服务端要区分不同Core版本。
还拿是否支持红包的判断举例。
一个App时:
booleanisSupportRedEnvelop(String appVersion){
returngte(appVersion, "2.1.0");
}
多个App时:
booleanisSupportRedEnvelop(Integer coreVersion){
returncoreVersion >= 2;
}
通过Core版本号,我们可以把兼容逻辑判断简化到和单个App一样的简单。
8、关于Core版本的命名和取值
关于Core版本号的取值,有下列可能的选项:
- 选项一:语义版本号 1.2.0;
- 选项二:整数 自然数 1 2 3;
- 选项三:整数 迭代日期 20220819 或 220819。
因为Core版本号不用给最终用户看的,无需遵循常见的语义版本号规范。而且Core版本号只用于版本对比,所以整数会是一个比较好的选择,方便比较,准确可靠。
用自然数1、 2、 3作为Core版本号是可以的,每个迭代发布新的Core版本时递增一下就可以了。
但是考虑到有多个终端平台iOS、Android、Windows、Mac,如果某个平台的Core发布后发现小Bug需要HotFix,那么要递增版本号,就会挤占其它端的下一个自然数。究其原因,在于自然数是连续的,没办法在两个常规的版本间插入一个HotFix版本。
选项三就可以解决这个问题:因为Core的迭代发布日期是稀疏的,若干天后才会发布一个Core版本,那么当某个端需要一个HotFix版本时,选择HotFix当天的日期作为版本号即可。
总体上:多个端的主要版本号都是约定的统一的发布日期,多端一致,同时允许某个端临时HotFix插入一个新的版本号,保留弹性。
参考 Google 对Android SDK API版本的实践,我们可以把Core版本号命名为core_level,取值为Core的发布日期的整数表示。
9、多个App情况下的其它版本标识
1)platform:
一套Core,不同端在实际开发中,可能存在差异,为了针对具体端进行特定的兼容,需要知道当前是哪个端,可以约定platform字段表示端。取值可以是:ios、android、win、mac、linux等。
2)App版本号:
在IM相关逻辑的兼容性判断中,只需使用跨App的多端一致的core_level了。但是为了和最终用户、产品经理等沟通方便,保留App版本号app_version用于人和人之间沟通交流。core_level主要用于研发工程师之间,还有工程师和程序之间的沟通。两者各取所长。
10、版本标识的传输方式
每个API和每条长连接数据包都携带Core版本,这样服务端可以无状态得处理每一个请求。如果需要在服务端主动推送时区分目标端的版本,可以在App登录时将其携带的Core版本落库存储,然后推送时查询使用。
10.1短连接(HTTP)
HTTP短连接通过新增Header字段方式传输:
curl "https://{domain}/api/v1/xxx"\
-H "platform: ios"\
-H "app_version: 8.0.25"\
-H "core_level: 220819"
10.2长连接(Socket)
长连接SDK通过类似HTTP Header的方式传输:
{
"platform":"ios",
"app_version":"8.0.25",
"core_level":"220819"
}
10.3短转长
短转长时HTTP Header会转换为长连接数据body里的header通过长链传递。
这样就同时存在长连接header和长连接body.header两套字段,最终以长连接body.header为准即可。
10.4其它
IM系统里的浏览器和小程序,如果可以新增HTTP Header则新增Header传输,实在没有办法可以通过User-Agent传输该信息,服务端优先解析Header,没有找到时再解析User-Agent。
服务端解析UA的正则表达式:
/ platform\/(ios|android|mac|win|linux) app_version\/([0-9]\.[0-9]+\.[0-9]+) core_level\/([1-9][0-9]+)( |$)/
以上正则表达式在线运行效果:点此查看。
11、本文小结
至此,我们找到了一个适用于多个App、多个子模块、多个功能点、临时BugFix的版本标识:Core版本号,这样就可以很好地解决多App的IM能力兼容性问题。
以下是版本兼容性判断伪码:
booleanisSupportRedEnvelop(Integer coreLevel) {
returncoreLevel >= 220819;
}
12、参考资料
[1]Browser vs Engine Version
[2]Node.js ABI version number
[3]Android SDK API Level
[4]零基础IM开发入门(一):什么是IM系统?
[5]一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
[6]一套原创分布式即时通讯(IM)系统理论架构方案
[7]从零到卓越:京东客服即时通讯系统的技术架构演进历程
[8]一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等
[9]基于实践:一套百万消息量小规模IM系统技术要点总结
[10]一套十万级TPS的IM综合消息系统的架构实践与思考
[11]从新手到专家:如何设计一套亿级消息量的分布式IM系统
[12]闲鱼亿级IM消息系统的架构演进之路
[13]深度解密钉钉即时消息服务DTIM的技术设计
[14]一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践
[15]企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
(本文已同步发布于:http://www.52im.net/thread-4202-1-1.html)
关键词:
-
全球速讯:[Termux]更换Termux源 安装Debian容器并 设置Debian镜像源且 安装code-server(附安卓/APK安装包+下载源+lan
前言Termux开发者称已经不会在GooglePlay上更新该应用了,要么在Github下载要么去F-Driod下载,为了方便下
来源: IM开发干货分享:IM客户端不同版本兼容运行的技术思路和实践总结
简单渗透测试流程-环球观速讯
天天快资讯:AIRIOT助力城市管廊工程,智慧物联守护城市生命线
全球速讯:[Termux]更换Termux源 安装Debian容器并 设置Debian镜像源且 安装code-server(附安卓/APK安装包+下载源+lan
笔记本gt630m相当于什么核显?笔记本GT630M显卡怎么样?
梦幻西游2需要点卡吗?梦幻西游2023新区开服表
IBMThinkPad笔记本电脑怎么一键还原?IBMThinkPad笔记本电脑怎么开机?
岳阳楼下诵经典|全球今日讯
大连市长城宽带DNS是多少?大连市长城宽带资费表
当前观察:硬盘预读参数变化分析
继烧烤后淄博代购也火了:网友都很想去
“五一”假期高速免费五天!提前出发的过省界收费站时注意时间 环球快播报
今日讯!五一这些景点门票已约满:游客注意别跑空
3200RPM超高转速 满速运转还不抖!酷冷至尊莫比乌斯120 OC风扇评测 环球报资讯
科幻工业风!红魔电竞显示器银翼版来了:极窄边框设计 热点评
贵阳市档案馆通过全国示范数字档案馆测试
Linux恢复文件双手锏|全球即时
世界热讯:基于Java开发的数字知识库,支持全文检索、知识图谱和工作流审批,太强大了
微资讯!聊一聊GIS之家团队数据案例源码共享以及在线体验
当前热讯:JasperReports教程_编程入门自学教程_菜鸟教程-免费教程分享
安装Amos结构方程模型分析软件的方法 环球热闻
兴齐眼药去年四季度起利润急降:“近视神药”网售被禁影响显现,正式上市时市场恐已成红海
7项技术行业唯一!vivo X Fold2今日首销:8999元起
五一档票房第一!王一博电影《长空之王》今日上映:歼-20真机硬核亮相_世界热头条
热议:四川瓦屋山首次发现猛禽之王:自然界顶级掠食者 海拔4000米以上活动
60架C919和40架ARJ21!海航豪购100架国产飞机 环球微头条
小鹏G6创意视频被指“侮辱科学家” 创作者发声:绝非侮辱而是致敬
证监会:下月公布虚拟交易平台发牌框架
每日聚焦:Docker获取Let`s Encrypt SSL 证书
天天热讯:【策略设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
一季度新接船舶订单量同比增53%(新数据 新看点) 环球看热讯
Win10再见!微软确认22H2为终极正式版 系统不再更新:2025年结束支持
价保618!真我GT Neo5降了:1TB版卖3299元 世界快报
比Wi-Fi 6快4倍!华为首测Wi-Fi 7:真机网速狂飙4.3Gbps 当前热门
全球快看:越来越黑化!《变形金刚1-7》女主角颜值变化 网友叹息黑人赢麻了
天风证券:4月第3周新能源汽车订单明显改善,车展有望带动终端需求回升
“欧佩克+”减产倒计时 中国能源供给如何摆脱新变数|环球今亮点
天天热文:北大校训是什么(北京大学的校训是什么)
新一轮国内油价今日调整 有望下调0.11元/升!中石油:油价过低不好 世界关注
世界热头条丨同事结婚行政到工位挨个收礼金被吐槽 还不请吃饭:网友热议别强迫
世界快看点丨史诗级升级!曝iPhone 15 Pro支持雷电3
世界热议:学系统集成项目管理工程师(中项)系列13b_人力资源管理(下)
当前速递!文移民合同范本(推荐4篇)
分享无人回应 爸爸退了家庭群:媒体点评称这是最起码尊重_每日信息
pandas 常见函数的使用 环球速讯
全球微动态丨[MoeCTF 2021]地狱通讯
《飞链云真实AI模特解决方案》
超越美国 我国核电机组2030年将达世界第一:第四代核电已有探索
内地引进!《变形金刚7:超能勇士崛起》正式预告发布:宇宙大帝来袭 焦点简讯
世界关注:国外品牌光环不再 你敢信车展排队半小时是为了看国产车?
7nm不让用!飞腾腾云5000C CPU公布:80核心变64核心 性能大大缩水_天天速递
锐龙7000多次烧毁 AMD闪电锁定“凶手”!果然猜对了
确山警方:一村(格)一警走访入户 筑牢安全防范根基 世界要闻
directx9.0c是什么软件 directx是什么软件_焦点关注
全球观天下!“逃离东北”的东北医生,多家医院因报名不足缩减岗位
2023国内外毫米波雷达行研分析 全球快播报
全球看热讯:前三月卖了55.2万辆车 比亚迪一季度营收破1200亿
每日播报!健身博主自曝因压力长六颗子宫肌瘤 专家:子宫肌瘤“偏爱”这3种人
《美猴王》发布剧照被吐槽丑 大圣更像大马猴:周星驰就这水平?
2023国内外毫米波雷达行研分析|天天速递
长沙雨花区坚持以稳定促发展 倾力为民解忧
腾讯代理!《无畏契约》国服5月2日开放下载:核显都能玩
快播:新能源汽车卖疯了 比亚迪一季度利润大涨410%:问鼎全球销冠
史上最大!苹果开发14寸新iPad:操作系统前所未有|全球今日报
太拼!春假首日孩子们在高铁上刷卷子:杭州小学生还要霸占北京景点
旅美大熊猫“乐乐”死因报告发布:心脏病变可能是主因
世界快报:热门中概股美股盘前涨跌不一,有道跌超6%
oop第二次作业 环球新要闻
Java中的Lambda详细解读
Linux再学!_全球简讯
10 如何表示虚拟内存
焦点快播:lua元表、元方法
世界即时看!知识产权保护为“中国制造”保驾护航 助力企业“走出去”
AI生成《原子之心》冰箱姐姐:身材超火辣!-全球快看点
天天观热点:AMD Zen4+RDNA3加持最强掌机!ROG Ally价格泄露:性能堪比PS5
《王国之泪》大量实机截图:菜谱来了!还有抽奖玩法-天天快报
全球首批机器受精试管婴儿出生:用PS5手柄操控机器人受精
OPPO第一季度销量登顶!用户点赞:售后非常好
武功县气象台发布大风蓝色预警【Ⅳ级/一般】【2023-04-27】
每日动态!nginx出现504错误的原因分析及解决
商品日报(4月27日):宏观面担忧加剧 原油系集体重挫|精彩看点
买皮肤也能“分期”了:《英雄联盟》加入点券分期付款功能
【世界报资讯】一次购买喝到爽!冻颜密码椰汁临期大促:9.9元/大瓶超值
雷军微博调研!米粉选出最喜欢的手机:小米13 Ultra排第二
每日消息!国产武侠《侠乂行》获支持:Intel发布4335显卡驱动
全球微资讯!中国空间站还能扩展:180吨级六舱合体、还可商业旅游
生存整个夜晚什么时候出 公测上线时间预告
全球焦点!REITs市场价格承压 长期投资价值回归
债市日报:4月27日_消息
好玩的奇迹mu手游有哪些 十大好玩的奇迹mu手游推荐
环球快消息!你的外卖“从天而降” 美团外卖无人机正式运行:15分钟内送达
环球即时看!日本又一核电站发生冷却水泄漏 电力公司回应:不会对外界有影响
专家呼吁企业增加带薪年假 称比调休更重要:5天太少
搭载卫星通信的手机盘点!它们都“捅破天”了:用一次续一升 前沿热点
焦点快报!1099元 微星推出G27C4X曲面屏:250Hz电竞高刷
当前快报:华为全屋智能重磅亮相AWE,以全空间、全场景、黑科技“打开空间之门”
led的点亮和流水灯的制作
pta第四次到第六次题目集_全球新资讯
记录-有意思的气泡 Loading 效果-世界微头条
Gitblit在Windows服务器下搭建及使用_微头条