您当前的位置:首页 > 电脑百科 > 程序开发 > 开源程序 > 源码

「开源精品」 C# im 聊天通讯架构 FreeIM 支持集群、职责分明、高性能

时间:2022-09-02 16:00:51  来源:今日头条  作者:IT狂人日记

FreeIM 是什么?

FreeIM 使用 websocket 协议实现简易、高性能(单机支持5万+连接)、集群即时通讯组件,支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 ImCore 已正式改名为 FreeIM。

使用场景:好友聊天、群聊天、直播间、实时评论区、游戏。

FreeIM 解耦了通讯与业务模块,让项目架构变得更加简单易维护,2017年的设计再过5年也不过时。

FreeIM 提供了一套永远不需要迭代更新的 ImServer 服务端,支持 .NET5.0、.NETCore2.1+、NETStandard2.0。

以及一套简单的 ImHelper API 提供给 业务端 使用,例如 ImHelper.SendMessage(a, b, 'hello world') 就可以实现 a -> b 发送消息。

开源地址:
https://Github.com/2881099/FreeIM


⛳ 项目由来

2017 年进朋友的公司救火,那个时候公司的人员架构、技术架构一团糟,例如通讯模块,配备了几人的全职团队负责工作,痛点如下:

1、IM服务端代码臃肿不堪;

2、逻辑混乱不堪,IM服务端代码包含了大量业务逻辑,例如聊天记录、订单数据,这本来应该是业务方的数据;

3、混乱持续放大,IM服务端为了适应需求,不断增加业务协议,越来越像业务端;

4、沟涌成本巨高,IM服务端经常和业务方开怼,比如某业务到底以谁的数据为准;

5、通讯协议失策,IM服务端使用原生Socket自定义通讯协议,后来要维护 WebSocket 及 自己定义协议两套,经常发生消息无法传输的问题;

FreeIM 架构的接入之后,解散了 IM 团队,解决了业务与通讯的职责冲突,简化了架构,降低了维护成本。经历 1年半的生产环境,整理代码于 2018 年开源。

我是不是太卷了。。别急啊,他们是 JAVA 团队,是不是瞬间舒服了


⚡ 如何接入?

dotnet add package FreeIM

1、ImServer 服务端

一套永远不需要迭代更新的IM服务端,ImServer 支持 .NET6.0、.NETCore2.1+、NETStandard2.0

public void Configure(IApplicationBuilder app){
    app.UseFreeImServer(new ImServerOptions
    {
        redis = new FreeRedis.RedisClient("127.0.0.1:6379,poolsize=5"),
        Servers = new[] { "127.0.0.1:6001" }, //集群配置
        Server = "127.0.0.1:6001"
    });
}

2、WebApi 业务端

public void Configure(IApplicationBuilder app){    //...

    ImHelper.Initialization(new ImClientOptions
    {
        Redis = new FreeRedis.RedisClient("127.0.0.1:6379,poolsize=5"),
        Servers = new[] { "127.0.0.1:6001" }
    });

    ImHelper.EventBus(
        t => Console.WriteLine(t.clientId + "上线了"), 
        t => Console.WriteLine(t.clientId + "下线了"));
}

ImHelper方法

参数

描述

PrevConnectServer

(clientId, string)

在终端准备连接 websocket 前调用

SendMessage

(发送者, 接收者, 消息内容, 是否回执)

发送消息

GetClientListByOnline

-

返回所有在线clientId

HasOnline

clientId

判断客户端是否在线

EventBus

(上线委托, 离线委托)

socket上线与下线事件

频道

参数

描述

JoinChan

(clientId, 频道名)

加入

LeaveChan

(clientId, 频道名)

离开

GetChanClientList

(频道名)

获取频道所有clientId

GetChanList

-

获取所有频道和在线人数

GetChanListByClientId

(clientId)

获取用户参与的所有频道

GetChanOnline

(频道名)

获取频道的在线人数

SendChanMessage

(clientId, 频道名, 消息内容)

发送消息,所有在线的用户将收到消息

  • clientId 应该与用户id相同,或者关联;
  • 频道适用临时的群聊需求,如聊天室、讨论区;

ImHelper 支持 .NetFramework 4.5+、.NetStandard 2.0

3、html5 终端

终端连接 websocket 前,应该先请求 WebApi 获得授权过的地址(
ImHelper.PrevConnectServer),伪代码:

ajax('/prev-connect-imserver', function(data) {    var url = data; //此时的值:ws://127.0.0.1:6001/ws?token=xxxxx
    var sock = new WebSocket(url);
    sock.onmessage = function (e) {        //...
    };
})

项目演示

运行环境:.NET6.0 + redis-server 2.8+

cd ImServer && dotnet run --urls=http://*:6001

cd WebApi && dotnet run

打开多个浏览器,分别访问 http://127.0.0.1:5000 发送群消息

 


分析痛点

协议痛点:如果浏览器使用 websocket 协议,IOS 使用其他协议,协议不一致将很难维护。

职责痛点:IM 的系统一般涉及【我的好友】、【我的群】、【历史消息】等等。。

ImServer 与 WebApi(业务方) 该保持何种关系呢?

用户A向好友B发送消息,分析一下:

  • 需要判断B是否为A好友;
  • 需要判断A是否有权限;

获取历史聊天记录,多个 终端 websocket.send('gethistory'),再在 onmessage 定位回调处理,多麻烦啊?

诸如此类业务判断会很复杂,使用 ImServer 做业务逻辑,最终 ImServer 和 终端 都将变成巨无霸难以维护。


设计思路

终端(如浏览器/小程序/iOS/Android) 统一使用 websocket 连接 ImServer;

ImServer(支持集群)根据 clientId 分区管理 websocket 连接;

WebApi 使用 ImHelper 调用方法(如:SendMessage、群聊相关方法),将数据推至 Redis channel;

ImServer 订阅 Redis channel,收到消息后向 终端 推送消息;

  • 缓解了并发推送消息过多的问题;
  • 解决了连接数过多的问题;
  • 解耦了业务和通讯,架构更加清淅;
    • ImServer 充当消息转发,连接维护,代码万年不变、且不需要重启维护
    • WebApi 负责所有业务

举例1、用户A向B发送消息:终端A ajax -> WebApi -> ImServer -> 终端B websocket.onmessage;

举例2、获取历史聊天记录:终端 请求 WebApi(业务方) 接口,返回json(历史消息)。

举例3、A向B发文件的例子:

  • A向 WebApi 传文件
  • WebApi 通知 ImServer,ImHelper.SendMessage(B, "A正在给传送文件...")
  • B收到消息,A正在给传送文件...
  • WebApi 文件接收完成时通知 ImServer,ImHelper.SendMessage(B, "A文件传输完毕(含文件链接)")
  • B收到消息,A文件传输完毕(含文件链接)

FreeIM 强依赖 redis-server 组件功能:

  • 集成了 redis 轻量级的订阅发布功能,实现消息缓冲发送,后期可更换为其他技术
  • 使用了 redis 存储一些关系数据,如在线 clientId、频道信息、授权信息等

集群分区

单个 ImServer 实例支持多少个客户端连接,3万?如果在线用户有10万人,怎么办???

部署 4 个 ImServer:

  • ImServer1 订阅 redisChanne1
  • ImServer2 订阅 redisChanne2
  • ImServer3 订阅 redisChanne3
  • ImServer4 订阅 redisChanne4

WebApi(业务方) 根据接收方的 clientId 后四位 16 进制与节点总数取模,定位到对应的 redisChannel,进行 redis->publish 操作将消息定位到相应的 ImServer。

每个 ImServer 管理着对应的终端连接,当接收到 redis 订阅消息后,向对应的终端连接推送数据。


事件消息

IM 系统比较常用的有上线、下线,在 ImServer 层才能准确捕捉事件,但业务代码不合适在这上面编写了。

此时采用 redis 发布订阅,将上线、下线等事件向指定频道发布,WebApi(业务方) 通过 ImHelper.EventBus 方法进行订阅捕捉。

 


有感而发

为什么说 SignalR 不合适做 IM?

1、IM 的特点必定是长连接,轮训的功能用不上;

2、因为 SignalR 是双工通讯的设计,终端 使用 hub.invoke 发送命令给 SignalR 服务端处理业务,适合用来代替 ajax 减少 http 请求数量;

3、过多使用 hub,SignalR 服务端会被业务入侵,业务变化频繁后不得不重新发布版本,每次部署所有终端都会断开连接,遇到5分钟发一次业务补丁的时候,类似离线和上线提示好友的功能就无法实现;

FreeIM 业务和推送分离设计,终端 连接永不更新重启 ImServer ,业务代码全部在 WebApi 编写,因此重启 WebApi 不会造成连接断开。


作者是什么人?

作者是一个入行 18年的老批,他目前写的.net 开源项目有:

开源项目

描述

开源地址

开源协议

FreeIM

聊天系统架构

https://github.com/2881099/FreeIM

MIT

FreeRedis

Redis SDK

https://github.com/2881099/FreeRedis

MIT

csredis

 

https://github.com/2881099/csredis

MIT

FightLandlord

斗DI主网络版

https://github.com/2881099/FightLandlord

学习用途

FreeScheduler

定时任务

https://github.com/2881099/FreeScheduler

MIT

IdleBus

空闲容器

https://github.com/2881099/IdleBus

MIT

FreeSql

ORM

https://github.com/dotnetcore/FreeSql

MIT

FreeSql.Cloud

分布式tcc/saga

https://github.com/2881099/FreeSql.Cloud

MIT

FreeSql.AdminLTE

低代码后台生成

https://github.com/2881099/FreeSql.AdminLTE

MIT

FreeSql.DynamicProxy

动态代理

https://github.com/2881099/FreeSql.DynamicProxy

学习用途

需要的请拿走,这些都是最近几年的开源作品,以前更早写的就不发了。

来自 叶老板



Tags:FreeIM   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
「开源精品」 C# im 聊天通讯架构 FreeIM 支持集群、职责分明、高性能
FreeIM 是什么?FreeIM 使用 websocket 协议实现简易、高性能(单机支持5万+连接)、集群即时通讯组件,支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 ImCore 已...【详细内容】
2022-09-02  Search: FreeIM  点击:(511)  评论:(0)  加入收藏
▌简易百科推荐
全网疯传的前端量子纠缠效果,源码来了!
昨天,很多群里都在疯传一个视频,视频演示了纯前端实现的“量子纠缠”效果,不少前端er表示:“前端白学了”。视频作者昨晚开源一个简化版的实现源码(截止发文,该项目在 Github 上已...【详细内容】
2023-11-24  前端充电宝  微信公众号  Tags:源码   点击:(420)  评论:(0)  加入收藏
深入浅出 OkHttp 源码解析及应用实践
一、MBR分区MBR是Master Boot Record的缩写,是一种旧的分区表格式,用于在硬盘上标识和管理分区。MBR分区表可以标识最多4个主分区或3个主分区和1个扩展分区。2TB的限制是指,使...【详细内容】
2023-05-18  雪竹频道  今日头条  Tags:OkHttp   点击:(340)  评论:(0)  加入收藏
用它就够了!开源的驾驶辅助系统
openpilot介绍openpilot是一个开源的驾驶辅助系统。目前,openpilot 执行自适应巡航控制 (ACC)、自动车道居中 (ALC)、前方碰撞警告 (FCW) 和车道偏离警告 (LDW) 的功能,适用...【详细内容】
2022-11-07  GitHub精选  今日头条  Tags:驾驶辅助   点击:(583)  评论:(0)  加入收藏
七爪源码:使用 NodeJs 观看文件系统
监视文件系统意味着监视特定目录或文件的更改。 有时您可能需要持续观察特定文件或目录的更改。出于这个原因,我们使用像 chokidar 这样的文件系统 Watcher 或内置的 NodeJs...【详细内容】
2022-09-17  庄志炎  今日头条  Tags:NodeJs   点击:(479)  评论:(0)  加入收藏
推荐 5 个开源的 yyds 效率神器
01 Wox:效率神器每次重装系统后,都会重新装一些常用的软件,Wox 这个国产开源免费的软件快捷启动工具是首装的效率工具。在 GitHub 上已经获得了 22k 的 Star。Wox 是一个高效的...【详细内容】
2022-09-16  互联网资讯看板  51CTO  Tags:开源   点击:(414)  评论:(0)  加入收藏
「开源精品」 C# im 聊天通讯架构 FreeIM 支持集群、职责分明、高性能
FreeIM 是什么?FreeIM 使用 websocket 协议实现简易、高性能(单机支持5万+连接)、集群即时通讯组件,支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 ImCore 已...【详细内容】
2022-09-02  IT狂人日记  今日头条  Tags:FreeIM   点击:(511)  评论:(0)  加入收藏
两款「工作流引擎」快速开发框架源码
推荐两款开源的工作流引擎快速开发框架,该工作流平台轻量简洁、美观快速、可扩展,易学习,能够快速上手进行二次开发。有需要的朋友可以去下载看看。(源码地址在文末)▶ 1:开发环境...【详细内容】
2022-08-23   互联网资讯看板  网易  Tags:框架   点击:(367)  评论:(0)  加入收藏
开源:一款开源的一站式SQL审核查询平台 - Archery
Archey介绍Archery是archer的分支项目,定位于SQL审核查询平台,旨在提升DBA的工作效率,支持多数据库的SQL上线和查询,同时支持丰富的MySQL运维功能,所有功能都兼容手机端操作. 功...【详细内容】
2022-08-10  IT搬砖人    Tags:Archery   点击:(771)  评论:(0)  加入收藏
spring源码解析-IOC容器的基本实现
大纲 容器的基本用法 spring启动过程分析(spring生命周期) bean 的生命周期 IOC核心类总结 常用扩展点容器的基本用法spring 是企业级开发框架, 主要功能有 IOC,AOP,Web,ORM...【详细内容】
2022-08-04  javabus    Tags:IOC容器   点击:(372)  评论:(0)  加入收藏
超低成本!自制linux开发板,全开源
这是一款低成本linux开发板——高性能异构边缘AI视觉开发板。作者参考树莓派A版型,将部分硬件替换。它的成本比树莓派低很多!却不一点比树莓派差!具体介绍如下!我还会...【详细内容】
2022-08-03  嘉立创EDA    Tags:开源   点击:(1082)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条