如何快速开发一套分布式IM系统
架构说明:
1)CIM 中的各个组件均采用 SpringBoot 构建;2)采用 Netty + Google Protocol Buffer 构建底层通信;3)Redis 存放各个客户端的路由信息、账号信息、在线状态等;4)Zookeeper 用于 IM-server 服务的注册与发现。

整体主要由以下模块组成:
1)cim-server——IM 服务端:用于接收 client 连接、消息透传、消息推送等功能。支持集群部署;2)cim-forward-route——消息路由服务器:用于处理消息路由、消息转发、用户登录、用户下线以及一些运营工具(获取在线用户数等);3)cim-client——IM 客户端:给用户使用的消息终端,一个命令即可启动并向其他人发起通讯(群聊、私聊);同时内置了一些常用命令方便使用。
流程解释如下:
1)客户端向 route 发起登录;2)登录成功从 Zookeeper 中选择可用 IM-server 返回给客户端,并保存登录、路由信息到 Redis;3)客户端向 IM-server 发起长连接,成功后保持心跳;4)客户端下线时通过 route 清除状态信息。
所以当我们自己部署时需要以下步骤:
1)搭建基础中间件 Redis、Zookeeper;2)部署 cim-server,这是真正的 IM 服务器,为了满足性能需求所以支持水平扩展,只需要注册到同一个 Zookeeper 即可;3)部署 cim-forward-route,这是路由服务器,所有的消息都需要经过它。由于它是无状态的,所以也可以利用 Nginx 代理提高可用性;4)cim-client 真正面向用户的客户端;启动之后会自动连接 IM 服务器便可以在控制台收发消息了。
这里就设计的比较简单,直接利用 Redis 来存储用户信息;用户信息也只有 ID 和 userName 而已。只是为了方便查询在 Redis 中的 KV 又反过来存储了一份 VK,这样 ID 和 userName 都必须唯一。

具体的流程:
1)登录成功之后需要判断是否是重复登录(一个用户只能运行一个客户端);2)登录成功后需要从 Zookeeper 中获取服务列表(cim-server)并根据某种算法选择一台服务返回给客户端;3)登录成功之后还需要保存路由信息,也就是当前用户分配的服务实例保存到 Redis 中。
为了实现只能一个用户登录,使用了 Redis 中的 set 来保存登录信息;利用 userID 作为 key ,重复的登录就会写入失败。
1)先从 Zookeeper 获取所有的服务实例做一个内部缓存;2)轮询选择一台服务器(目前只有这一种算法,后续会新增)。即时通讯聊天软件app开发可以加小蓝豆的v:weikeyun24咨询即可
当然要获取 Zookeeper 中的服务实例前自然是需要监听 cim-server 之前注册上去的那个节点。
这是一个真正发消息的接口,实现的效果就是其中一个客户端发消息,其余所有客户端都能收到!流程肯定是客户端发送一条消息到服务端,服务端收到后在上文介绍的 SessionSocketHolder 中遍历所有 Channel(通道)然后下发消息即可。服务端是单机倒也可以,但现在是集群设计。所以所有的客户端会根据之前的轮询算法分配到不同的 cim-server 实例中。
由于 Redis 单线程的特质,当数据量大时;一旦使用 keys 匹配所有 cim-route:* 数据,会导致 Redis 不能处理其他请求。所以这里改为使用 scan 命令来遍历所有的 cim-route:*。
接着会挨个调用每个客户端所在的服务端的 HTTP 接口用于推送消息。
之所以说获取在线用户是一个辅助接口,其实就是用于辅助私聊使用的。一般我们使用私聊的前提肯定得知道当前哪些用户在线,接着你才会知道你要和谁进行私聊。
所以私聊接口在收到消息后需要查询到接收者所在的 cim-server 实例信息,后续的步骤就和群聊一致了。调用接收者所在实例的 HTTP 接口下发信息。只是群聊是遍历所有的在线用户,私聊只发送一个的区别。
相关文章:
如何快速开发一套分布式IM系统
架构说明: 1)CIM 中的各个组件均采用 SpringBoot 构建;2)采用 Netty Google Protocol Buffer 构建底层通信;3)Redis 存放各个客户端的路由信息、账号信息、在线状态等;4)Zookeeper …...
W806|CKLINK LITE|调试|elf文件模板|CSDK|Debug|学习(4):CKLINK调试W806
一、硬件连接 接线方式 (连线颜色供参考,本例中采用图示颜色): 注意:CKLINK LITE的3V3须与W806的3V3相连,或者给W806开发板单独供电,两种方式均可。 否则,会提示“the referenc…...
【100个 Unity实用技能】 ☀️ | 脚本无需挂载到游戏对象上也可执行的方法
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。Unity 平台提供一整套完善的软件解决方案ÿ…...
「IT女神勋章」挑战赛#
缓存 本地缓存 本地缓存为了保证线程安全问题,一般使用ConcurrentMap的方式保存在内存之中 分布式缓存。 常见的分布式缓存则有Redis,MongoDB等。 一致性:本地缓存由于数据存储于内存之中,每个实例都有自己的副本,…...
易优cms user 登录注册标签
user 登录注册标签 user 登录注册入口标签 [基础用法] 标签:user 描述:动态显示购物车、登录、注册、退出、会员中心的入口; 用法: {eyou:user typeuserinfo} <div id"{$field.htmlid}"> …...
源码安装Redis 7.0.9并且systemctl管理
以下是在/usr/local/redis中通过源代码安装Redis 7.0.9并将其加入systemctl管理的步骤: 首先,下载Redis 7.0.9源代码包: wget https://download.redis.io/releases/redis-7.0.9.tar.gz解压缩Redis源代码包: tar xzf redis-7.0.9…...
编写程序:有92号和95号汽油可以选择,选择你需要的汽油,并输入需要加油的升数,点击按钮“`计算总价钱`“在div中可以得到你所需要支付的价格
需求: 有92号汽油和95号可以选择,选择你需要的汽油,并输入需要加油的升数,点击按钮"计算总价钱"在div中可以得到你所需要支付的价格。结构如下图所示: 详细代码如下: <!DOCTYPE html> &l…...
参考文献去哪里查找,参考文献标准格式是什么
1、参考文献类型: 普通图书[M]、期刊文章[J]、报纸文章[N]、论文集[C]、学位论 文[D]、报告[R]、标准[s]、专利[P]、数据库[DB]、计算机程序[CP]、电 子公告[EB]、联机网络[OL]、网上期刊[J/OL]、网上电子公告[EB/OL]、其他未 说明文献[z]。…...
WIFI标签操作步骤
1. 打开并设置手机WIFI热点,设置SSID为ESL,密码为123456789(如下图) 2. 运行APP,设置要接入的WIFI名称密码等信息(如下图) 3. 长按背面按键(长按2-3秒),…...
【Hello Linux】命令行解释器
作者:小萌新 专栏:Linux 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:使用进程的基础知识和进程控制知识做出一个简单的shell程序 命令行解释器介绍搭架子缓冲区获取命令如何从标准输入中获取字符串解析命令…...
开源一个通用的 HTTP 请求前端组件
像 Postman 这样可视化的 HTTP 请求工具是调试 API 不可或缺的利器。Postman 虽好但也越来越重,而且如果要整合到其他工具中,显然 Postman 又不是一个可行的方案。于是我想打造一个简单的前端组件(widget),它是一个标准…...
等保测评机构资质申请条件是什么?个人可以申请吗?
最近看到不少网友在问,等保测评机构资质申请条件是什么?个人可以申请吗?今天我们小编就来给大家详细回答一下。 等保测评机构资质申请条件是什么?个人可以申请吗? 【回答】:首先需要明确一点的是…...
android 卡顿、ANR优化(1)屏幕刷新机制
前言: 本文通过阅读各种文章和源码总结出来的,如有不对,还望指出 目录 正文 基础概念 视觉暂留 逐行扫描 帧 CPU/GPU/Surface: 帧率、刷新率、画面撕裂 画面撕裂 Android屏幕刷新机制的演变 单缓存(And…...
Landsat8中*_MTL.txt文件详解
01 什么是*_MTL.txt文件?所有的Landsat8 1级数据产品中均包含MTL.txt(Metadata File)文件。Landsat MTL文件包含对数据的系统搜索和归档分类有益的信息。该文件还包含关于数据处理和恶对增强陆地卫星数据有重要价值的信息(例如转换为反射率和辐射亮度&am…...
好的提高代码质量的方法有哪些?有什么经验和技巧?
用于确保代码质量的6个高层策略: 1 编写易于理解的代码 考虑如下这段文本。我们有意地使其变得难以理解,因此,不要浪费太多时间去解读。粗略地读一遍,尽可能吸收其中的内容。 〓ts〓取一个碗,我们现在称之为A。取一…...
yum保留安装包
一. 用downloadonly下载 1.1 处理依赖关系自动下载到/tmp/pages目录,pages这个目录会自动创建 yum install --downloadonly --downloaddir/tmp/pages ceph-deploy注意,如果下载的包包含了任何没有满足的依赖关系,yum将会把所有的依赖关系包下…...
ERP系统哪家比较好?
ERP系统哪家好?在选择ERP系统时,我们可以按照这三个维度,然后再按照需求去选择ERP系统。 市面上ERP软件大概可以分为三大类: ① 标准ERP应用:功能比较固定,难以满足个性化需求,二次开发难度很高…...
Python读写mdb文件的实战代码
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...
MAC和IP地址在字符串形式、数字形式和byte数组中的转换
MAC地址 mac地址作为网卡的物理地址,有6个byte的长度。在实际表示形式上,以每个字节的16进制,中间用冒号隔开,比如:“01:02:03:04:05:06”。这就是mac地址的字符串形式 而在网络通信传输中,需要对mac地址从字符串形式转换为数字形式或byte数组形式发送。并且网络上传输…...
时间轮来优化定时器
在raft协议中, 会初始化三个计时器是和选举有关的: voteTimer:这个timer负责定期的检查,如果当前的state的状态是候选者(STATE_CANDIDATE),那么就会发起选举 electionTimer:在一定时…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
