IM序列9:浅谈移动端IM的多点登陆和消息漫游原理

1、前言

在移动端IM大行其道之前的PC端IM时代,所谓的多端登陆控制无非就是当你在一台电脑上登陆后,再在另一台电脑上登陆时就会把之前登陆的账号给踢出(比如QQ就是这样)。同样PC端时代的IM消息漫游不过就是可以在另一台电脑上下载之前的历史记录而已(参考PC端QQ)。

但自从Google在2013年的开发者大会(Google I/O)上公布了一款叫“Google 环聊”(网址:hangouts.google.com)的移动端IM后,凭借Google的创意,多端登陆和消息漫游才真正有了现在的体验(Google环聊无法体验的话,参考当前版本的微信、手机QQ就可以了):即允许同一账号在多种设备上同时登陆和使用、且消息会以某种逻辑同步到另外的端上(包括自已发出的消息)等特性,使用得移动端IM的消息同步第一次真正的变的友好和易用。

本文将展开聊聊移动端IM“多点登陆”与“消息漫游”的原理。

2、IM开发干货系列文章

《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》

《IM消息送达保证机制实现(二):保证离线消息的可靠投递》

《如何保证IM实时消息的“时序性”与“一致性”?》

《IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?》

《IM群聊消息如此复杂,如何保证不丢不重?》

《一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)》

《移动端IM登录时拉取数据如何作到省流量?》

《通俗易懂:基于集群的移动端IM接入层负载均衡方案分享》

《浅谈移动端IM的多点登陆和消息漫游原理》(本文

3、基本概念

什么是多点登录?

以微信为例:可以PC端、phone端同时登录、同时收发消息。需要注意的是:一个端只能登录一个实例,例如同一个QQ号,在pc1上登录再到pc2上登录,后者会把前者踢出,pc1会收到通知“你已在别处登录xxoo”。

什么是消息漫游?

在任何一个终端的任何一个实例登录qq,都能够拉取到所有历史聊天消息,这个就是消息漫游。微信目前只支持“多点登录”同时收发在线消息(如果你同时开过PC端微信和手机端微信,你可以注意到你收到和发出的消息都会在另一个端同时显示出来),没有实现“消息漫游”,潜台词是:登出手机微信,登录PC微信,聊天,再登录手机微信是看不到历史消息的。

4、一个典型的IM消息收发架构

image

整个IM的架构可以抽象成这么几层:

1)客户端:例如pc微信,手机qq

2)服务端:

    2.1)入口层gate集群:能够水平扩展,保持与客户端的连接;

    2.2)逻辑层logic、路由层router集群:高可用可扩展,实现业务逻辑,进行消息的路由;

    2.3)cache:高可用cache集群,用来存储用户的在线状态,与接入节点(用户具体连接在哪个gate节点);

    2.4)db:固化存储消息,群信息,好友关系链等信息。

一个典型的消息收发流程如上图步骤1-5:

1)用户A登录在gate1上,发出消息;

2)gate1将消息给logic/router;

3)logic/router查询接收方的在线状态(B在线,C不在线);

4)例如接收方C不在线,存储离线;

4)例如接收方B在线,且登录在gate2上,消息投递给gate2;

5)gate2将消息投递给B。

当然,单对单消息有一系列应用层超时、重传、确认、去重的机制,这不是本文的重点,不进行展开,细节详见《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》、《IM消息送达保证机制实现(二):保证离线消息的可靠投递》。

5、接收方多点登陆时的消息投递原理

image

接收方多点登录:pc登录、phone也登录,后一端登录不会将前一端踢出,cache中存储状态与登录点时,不再以user_id为key,改为以user_id+终端类型为key即可。

传统的PC端IM时的B客户端信息为:online(状态),gate2(登录点)。

在支持多端登陆的移动端IM时信息应改为:

B的pc客户端:online(状态),gate2(登录点);

B的phone客户端:online(状态),gate3(登录点)。

当用户A给用户B发送消息时,取出所有B的登录点,进行消息群发即可(如上图中步骤4与步骤5)。

6、发送方多点登陆时的消息投递原理

有朋友可能要问,发送方和多点登录有什么关系?

假设用户A登录了两个点:A1和A2;用户B登录了两个点B1和B2:

A(A1发出的)发送消息给B(B1和B2);

B(B1发出的)发送消息给A(A1和A2)。

不就可以了么?

其实不然:A(A1发出的)发送消息给B(B1和B2),B(B1发出的)发送消息给A(A1和A2)。A2端虽然收到了所有B回复的消息,但消息其实是在A1端发出的,故A2端只知道聊天消息的一半(所有B的回复),缺失了聊天的上下文(所有A1端的发出)。故:如果发送方也进行了多点登录,发送出去的任何消息,除了要投递给多点登录的接收方,还需要投递给多点登录的发送方(说白了就是自已发出的消息,也要发送到自已登陆的其它客户端上)。

image

如上图所示,发送方A和接收方B都进行了多点登陆,服务端cache中存储的信息为:

A的pc端:online(状态),gate0(登录点);

A的phone端:online(状态),gate1(登录点);

B的pc端:online(状态),gate2(登录点);

B的phone端:online(状态),gate3(登录点)。

当用户A(phone端)给用户B发送消息时,除了要投递给B的所有多点登录端,还需要投递给A自已多点登陆的其他端(pc端),如上图中步骤4与步骤5。只有这样,才能在所有用户的所有端,恢复与还原双方聊天的上下文。

7、消息漫游原理

如果业务不需要支持“消息漫游”的功能,对于在线消息,如果用户实时接收到则是不需要存储到数据库的。但如果要支持“换一台机器(指的是用户的客户端)也能看到历史的聊天消息”,就需要对所有消息进行存储了。

image

消息投递如上图:用户A发送消息给用户B,虽然B在线,仍然要增加一个步骤2.5,在投递之前进行存储,以备B的其他端登陆时,可以拉取到历史消息。

image

消息拉取如上图:原本不在线的B(phone端),又重新登录了,他怎么拉取历史消息?只需要在客户端本地存储一个上一次拉取到的msg_id(time),到服务端重新拉取即可。这里还有个问题:由于服务端存储所有消息成本是非常高的,所以一般“消息漫游”是有时间(或者消息数)限制,不能拉取所有所有几年前的历史消息,比如只能拉取3个月内的云端消息等。

8、本文小结

“多点登录”是指多个端同时登录一个帐号,同时收发消息,关键点是:

1)需要在服务端存储同一个用户多个端的状态与登陆点;

2)发出消息时,要对发送方的多端与接收端的多端,都进行消息投递。

“消息漫游”是指一个用户在任何端,都可以拉取到历史消息,关键点是:

1)所有消息存储在云端;

2)每个端本地存储last_msg_id,在登录时可以到云端同步历史消息;

3)云端存储所有消息成本较高,一般会对历史消息时间(或者条数)进行限制。

附:本系列文章参考“架构师之路”等网上文章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容