常见的社交软件聊天模型都在这里,看完你也可以自己做个IM

 昨天,头条又上了一款新的社交软件飞聊,最近这段时间,新的社交软件层出不穷,好像做一款IM软件就没什么难度,今天我们来聊一聊,像飞聊、微信这些聊天软件是如何设计的,常见的IM模型长啥样,是如何做到不丢消息的。消息系统是每个聊天软件的核心,如果一个聊天软件连消息都丢,那是非常可怕的,例如昨天520,跟心仪的妹纸表达之后,却迟迟得不到回应,以为对方拒绝了,实际上对方并没有收到。当然想跟妹纸聊天,首先你得知道哪里有妹纸,妹纸在哪里?服务器告诉你。

直连模型


很多没做过IM的人都会有这样的想法,两个人聊天跟服务器有什么关系,两个人就互相建立socket开始聊天了么?最多就是从服务器查询到对方的地址在哪里,双方建立连接的可以了么?在这里,服务器的作用相当于媒婆,只是告诉你,对方的联系方式。事实上,这种模型并不是不存在,在服务器资源匮乏的时候,有些IM软件就使用这种设计。这种设置的好处是服务器非常的轻量级,但实际上却是非常的不方便,一是用户的地址经常变化,二是消息没有落到服务器系统,没法进行消息漫游,三是无法进行监管,你不知道用户发了什么东西,容易引发一些其他问题。

推送模型


这是第二种常见的IM软件模型,据说早期的QQ就是这种设计模型。用户与服务器建立长连接,发送方把发送内容发送到服务器上面,服务器再看看接收方是否在线,通过长连接,把消息推送到用户乙,推送成功后,再告诉甲你的消息已经发送成功了。显而易见,这种模型我们就可以在服务器上面把用户的消息记录也存储下来,用户也可以查询到自己的历史聊天记录。


这种模型几乎解决了上一个模型的所有缺点,用户不用再关心对方的地址,也可以进行消息漫游了。但也带来了一些问题,一是维护长连接需要一定的成本,二是用户不在线或者消息失败各种重试的逻辑会变得更加复杂。在移动互联网刚刚兴起的时候,4G网络还没有普及,用户的信号很差,网速很慢,这种模型经常造成用户丢消息。

拉取模型


既然用户网速很慢很不稳定,推送给用户的消息经常不成功,那就让用户自己来拉取吧。早期微信的聊天模型借鉴了邮箱的收发模型。每个用户都有一个收信箱,客户端会维护自己的已经收了哪些消息,再定时上来服务器询问,有没有新的消息。那么用户发送消息的时候是什么样子的呢?一次用户的发送消息,只要确保两个人的信箱都写入成功,那么就认为消息是发送成功的。


至于另外一个用户,则定时去查询自己的收件箱里面有新没有新的信息,他也不关心这个信息是谁发送的,先把这个信息收下来,开打信息之后,才能看到是谁发送过来的。


这个模型下面,让发送跟接收两个动作都非常的轻量级,而且重试机制非常的简单,发送的时候,如果插入对方的收信箱失败,只要简单的回滚自己的插入操作,返回失败让客户端重试即可。接收的时候,只有整条链路都成功,才会更新本地的版本号,不然客户端还是会继续向服务器查询,拿到失败的数据继续重试。举个简单的例子,假设乙本地的信箱版本是5,服务器的信箱版本是7,乙向服务器拿到6,7的数据,在消息回到客户端的时候,信号不好,消息丢了,那么客户端不会更新本地的版本,下一次还是向服务器询问比5大的信箱数据,再一次拿到6,7的数据。在此基础上,我们再保证双方收信箱的存储高可用,这里可以简单地使用主从存储之类的,我们之前也分享过,或者使用paxos等分布式协议,保证多个存储的数据一致性。这么说,微信、飞聊这些聊天软件都是没什么难度的咯?非也,在互联网应用中,难度是随着用户量指数增长的,有10亿用户的软件开发维护难度可能是有1亿用户的软件的100倍!今天的介绍我们就讲到这里,如果你有兴趣,欢迎关注我,除了分享算法相关的,最近主要会讲一些redis的原理与应用。近期还准备了一些AI相关的知识,整理后会和大家继续分享。大家的支持是我继续唠嗑的动力。

相关产品

评论