本文译自Codin Gurukul经OpenIM技术人员整理修订后发布。
写在前面
Open-IM是由前微信技术专家打造的开源的即时通讯组件。Open-IM包括IM服务端和客户端SDK,实现了高性能、轻量级、易扩展等重要特性。开发者通过集成Open-IM组件,并私有化部署服务端,可以将即时通讯、实时网络能力快速集成到自身应用中,并确保业务数据的安全性和私密性。
了解更多原创文章:
【OpenIM原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型
【OpenIM原创】C/C++调用golang函数,golang回调C/C++函数
【OpenIM原创】简单轻松入门 一文讲解WebRTC实现1对1音视频通信原理
【OpenIM扩展】OpenIM服务发现和负载均衡golang插件:gRPC接入etcdv3
【开源OpenIM】高性能、可伸缩、易扩展的即时通讯架构
实时消息现在是我们日常生活中必不可少的一部分。但是,你有没有想过“WhatsApp”或其他实时消息应用程序是如何工作的?
在本文中,我们将探讨whatsapp或任何通用实时消息应用程序背后的高级工程和系统架构。
在深入研究之前,让我们先了解“通讯是如何工作的?
当两个客户机(A和B)想要相互通信或发送消息时,他们首先知道对方的地址(可能是IP、MAC或任何自定义的唯一标识),然后通过网络彼此交换消息,在这种情况下是INTERNET。这个就是所谓的p2p通信了。
但是,如果网络非常庞大,客户数量达到数百万或数十亿,该怎么办?
在一个非常大的网络中,很难知道每个客户机的地址,在这种情况下,为了使这个系统更加健壮和高可用性,我们需要在客户机之间安装一个名为“服务器”的组件。此服务器的任务是协调连接到它的所有客户端,中转双方之间的消息。
服务器引入后。所有客户端都与服务器连接,而不是彼此连接,这样成了中心化的通讯架构
在这种情况下,当一个客户机(a)想要向其他客户机(D)发送消息时,它首先将消息发送到服务器,服务器知道其他客户机(D)的地址,然后将消息转发给其他客户机(D),反之亦然。
这是通信体系结构的概述。让我们设计一个实时消息传递系统的实际系统设计。
但在设计任何产品之前,了解以下要求非常重要:
用户群:了解应用程序的使用规模非常重要。
所需功能
那么,让我们列出whatsapp中需要包含的一些功能:
1). 发消息
2). 多媒体支持
3). Last Seen
4). 消息加密
5). 音频/视频通话
根据应用程序需求设计系统
根据应用程序需求设计系统
根据用户群,我们需要多台服务器来处理如此多的流量,因此我们放置了多台服务器,而不是一台服务器,这就是集群的概念
但问题是,客户端将连接到哪个服务器,因为有多个服务器,并且客户端不能随机连接到任何服务器。为了克服这个问题,我们在客户端和服务器之间引入了负载均衡。
在实现了多个服务器和负载平衡器之后,我们的系统架构能够处理大量用户。现在,当客户机想要连接到服务器时,连接请求首先命中负载平衡器,然后负载平衡器根据各个服务器上的负载等各种参数将连接重定向到服务器。
但我们的应用程序也需要一些存储机制来保存一些任意状态或数据,为了满足这一要求,我们还添加了可供所有服务器访问的数据库。
但是,使用什么样的连接呢?
通常,这种系统使用双工连接或双向连接。由于消息也可以从服务器生成,因此需要双向通信
在继续之前,让我们先了解不同的连接场景以及应用程序的工作方式。
当发送方连接到服务器而不是接收方时。
在这种情况下,当接收方未连接到服务器时,消息存储在数据库中,当接收方连接到服务器时,消息从数据库中提取并转发给接收方,这个就是离线消息的作用。
2.当发送方未连接到服务器时。
在这种情况下,当发送方未连接到服务器时,发送方发送的消息将保存在设备本地存储中(可能是SQLite或基于平台的任何其他内容)。当发送者联机或连接到服务时,消息将从本地存储中提取并发送到服务器。这个就是本地存储的作用。
3.当两个客户端都连接到服务器时:
在这种情况下,当两个客户端都连接到服务器时,发送方发送消息,服务器将该消息转发给接收方,而不将消息存储到数据库或设备本地存储器。
需要知道的一件事是,连接总是由客户机启动的,因为服务器不知道客户机的地址,但客户机知道服务器的地址。
发送、交付和查看三个状态
发送:当我们发送一条消息,而该消息被Whatsapp服务器接收时。
已传递:当消息从Whatsapp服务器传递到接收方时。
已查看:当信息被接收者看到/打开时。
为了合并所有这些状态更改,每条消息都有一个唯一的ID,用于标识每条消息以及来自各种事件(已发送/已交付/已查看)的确认。
当客户端连接到服务器时,Whatsapp服务器内部会发生什么?
当客户端连接到WhatsApp服务器时,将针对该客户端创建一个进程(或线程)。此流程负责处理与该客户机相关的所有操作。
每个进程都有一个队列(以浅绿色突出显示),作为该进程的缓冲区。创建流程后,将在数据库中创建一个表,以维护PID(流程ID)和关联客户机的记录。
Last Seen是怎么回事?
这个特性的实现非常简单和直接,它只需要维护一个带有客户机ID和时间戳的记录。
我们在智能手机中打开Whatsapp时,我们的应用程序每5秒向服务器发送一个脉冲,并且随着每个脉冲最后一次出现,表中的时间会更新。当客户端断开连接时,记录中存在上次看到的时间,该时间由关闭应用程序之前发送的最后一个脉冲更新。
媒体共享是如何运作的?
对于共享,我们不使用用于发送文本消息的连接,因为它是一个非常轻量级的连接,无法处理这么多负载。
相反,WhatsApp使用不同的服务器(如HTTP)来共享媒体。
当我们共享一个媒体时,它会通过不同的连接上传到HTTP服务器,成功上传后,HTTP服务器会返回一个与该媒体相关联的哈希值或唯一ID,该哈希值会发送到WhatsApp服务器。在接收方端,同样的事情以相反的方式工作,接收方接收哈希值,然后从与该哈希值关联的HTTP服务器下载媒体。
电话服务也以与媒体服务相同的方式工作,为此,我们还使用不同的服务器,并使用不同类型的连接(如套接字等)进行实时通信。
OpenIM github开源地址:
https://github.com/OpenIMSDK/Open-IM-Server
OpenIM官网 :https://www.rentsoft.cn
OpenIM官方论坛:https://forum.rentsoft.cn
我们致力于通过开源模式,为全球企业/开发者提供简单、易用、高效的IM服务和实时音视频通讯能力,帮助开发者降低项目的开发成本,并让开发者掌控业务的核心数据。
IM作为核心业务数据,安全的重要性毋庸置疑,OpenIM开源以及私有化部署让企业能更放心使用。
如今IM云服务商收费高企,如何让企业低成本、安全、可靠接入IM服务,是OpenIM的历史使命,也是我们前进的方向。
如您有技术上面的高见请到我们的论坛联系沟通,用户也可与我们的技术人员谈讨使用方面的难题以及见解