[重磅开源] 比SingleR更适合的websocket 即时通讯组件---ImCore开源了
有感而发
为什么说 SignalR 不合适做 IM?
IM 的特点必定是长连接,轮训的功能用不上。
因为它是双工通讯的设计,用hub.invoke发送命令给服务端处理业务,其他就和 ajax 差不多,用来代替 ajax 减少 http 请求数量比较看好。
但是过多使用 hub,SignalR 服务端会被业务入侵严重,业务变化频繁后不得不重新发布版本,每次部署所有终端都会断开连接,遇到5分钟发一次业务补丁的时候,类似离线和上线提示好友的功能就无法实现。
ImCore 的设计是业务和推送分离,即 ImServer 永不更新重启,业务全部在 webApi 上编写,终端连接的 ImServer 就不会频繁重启的问题。
为什么说又呢?
熟悉叶先森的朋友应该都知道,他之前开源了两款比较热门的组件,如:
CSRedisCore
: 操作Redis的简单易用的组件。GitHub:https://github.com/2881099/csredis 目前也已经八百多星了,nuget下载量也已经121k了.相关介绍及使用可以参考《.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐》
FreeSql
:FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+。这个可以说是比EFCore更好用的一个ORM组件了。这个组件目前也已经有八百多星了,nuget下载量也已经13.9k了。GitHub地址:https://github.com/2881099/FreeSql 。据说用了这个组件后头发都茂密了起来。
而且上面两个组件我也一直在用,感觉很方便。有兴趣的小伙伴可以.net core两千人群交流讨论:637326624
ImCore是什么
ImCore是一个利用 WebSocket 实现简易、高性能、集群化部署的即时通讯组件,支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。
Quick Start
dotnet add package ImCore
IM服务端
public void Configure(IApplicationBuilder app)
{
app.UseImServer(new ImServerOptions
{
Redis = new CSRedis.CSRedisClient("127.0.0.1:6379,poolsize=5"),
Servers = new[] { "127.0.0.1:6001" }, //集群配置
Server = "127.0.0.1:6001"
});
}
一套永远不需要迭代更新的IM服务端
WebApi业务端
public void Configure(IApplicationBuilder app)
{
//...
ImHelper.Initialization(new ImClientOptions
{
Redis = new CSRedis.CSRedisClient("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 |
EventBus | (上线委托, 离线委托) | socket上线与下线事件 |
群聊频道 | 参数 | 描述 |
---|---|---|
JoinChan | (clientId, 频道名) | 加入 |
LeaveChan | (clientId, 频道名) | 离开 |
GetChanClientList | (频道名) | 获取群聊频道所有clientId |
GetChanList | - | 获取所有群聊频道和在线人数 |
GetChanListByClientId | (clientId) | 获取用户参与的所有群聊频道 |
GetChanOnline | (频道名) | 获取群聊频道的在线人数 |
SendChanMessage | (clientId, 频道名, 消息内容) | 发送群聊消息,所有在线的用户将收到消息 |
说明:clientId 应该与 webApi的用户id相同,或者有关联。
Html5终端
本方案支持集群分区,前端连接 websocket 前,应该先请求 webApi 获得地址(ImHelper.PrevConnectServer)。
运行示例
运行环境:.NETCore 2.1 + redis-server 2.8
下载Redis-x64-2.8.2402.zip,点击 start.bat 运行;
cd imServer && dotnet run
cd web && dotnet run
打开多个浏览器,访问 http://127.0.0.1:5000 发送群消息
设计思路
ImServer 是 websocket 服务中心,可部署多实例,按clientId分区管理socket连接;
webApi 或其他应用端,使用 ImHelper 调用相关方法(如:SendMessage、群聊相关方法);
消息发送利用了 redis 订阅发布技术。每个 imServer 订阅相应的频道,收到消息,指派 websocket 向终端(如浏览器)发送消息;
1、可缓解并发推送消息过多的问题;
2、可解决连接数过多的问题;
客户端连接流程:client -> websocket -> imserver
imserver 订阅消息:client <- imserver <- redis channel
推送消息流程:web1 -> sendmsg方法 -> redis channel -> imserver
imserver 充当消息转发,及维护连接中心,代码万年不变不需要重启维护;
WebSocket
比较笨的办法是浏览器端使用websocket,其他端socket,这种混乱的设计非常难维护。
强烈建议所有端都使用websocket协议,websocket协议支持几乎所有端,adorid/ios/h5/小程序全部支持websocket客户端。
websocket用了后,就像跨平台。。。虽然选一种语言都能连接通讯。
业务与通讯协议
im系统一般涉及【我的好友】、【我的群】、【历史消息】等等。。
那么,imServer与业务方(webApi)该保持何种关系呢?
用户A向好友B发送消息,分析一下:
- 需要判断B是否为A好友;
- 需要判断A是否有权限;
- 等等。。
诸如此类业务判断会很复杂,我们试想一下,如果使用imServer做业务协议,它是不是会变成巨无霸难以维护?
又比如获取历史聊天记录,难道客户端要先websocket.send('gethistory'),再在onmessage里定位回调处理?
我们可以这样设定,所有用户的主动行为走业务方(webApi),imServer只负责即时消息推送。什么意思?
用户A向好友B发送消息:客户端请求业务方(webApi)接口,由业务方(webApi)后端向imServer发起推送请求,imServer收到指令后,向前端用户B的websocket发送数据,用户B收到了消息。
获取历史消息:客户端请求业务方(webApi)接口,返回json(历史消息)
回执:用户A如何知道消息发送状态(成功或失败或不在线)?imServer端向用户B发送消息时,把状态以消息的方式推给用户A即可(按上面的逻辑),具体请看源码吧。。。
发送消息
业务和推送分离的设计,即 imServer 只负责推送工作。
用户A向B发消息:终端A ajax -> webApi -> imServer -> 终端B WebSocket.onmessage;
采用 redis 轻量级的订阅发布功能,实现消息缓冲发送。
redis 缓冲消息发送,避免对业务方(webApi)造成消息发送的性能损耗,属于必备,也可以更换为其他技术。
比如 webapi 业务发需要通知1000个人,不用消息缓冲的话。。。
还有使用redis存储一些数据,如在线clientId,群聊结构。
集群分区
单个imServer实例支持多少个客户端连接,两千个没问题?
如果在线用户有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 方法进行订阅捕捉。
A向B发文件的例子
1、A向webapi传文件
2、webapi告诉imServer,A向B正在传文件
3、B收到消息,A正在传文件
4、webapi文件接收完成时告诉imServer,A向B文件传输完毕
5、B收到消息,A文件传输完成(含文件链接)
[重磅开源] 比SingleR更适合的websocket 即时通讯组件---ImCore开源了的更多相关文章
- [开源] .NETCore websocket 即时通讯组件---ImCore
前言 ImCore 是一款 .NETCore 下利用 WebSocket 实现的简易.高性能.集群即时通讯组件,支持点对点通讯.群聊通讯.上线下线事件消息等众多实用性功能. 开源地址:https:// ...
- Springboot 项目源码 Activiti6 工作流 vue.js html 跨域 前后分离 websocket即时通讯
特别注意: Springboot 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮) 后台框架:springboot2.1.2+ activiti6.0.0+ mybaits+maven+接 ...
- java SSM框架 代码生成器 快速开发平台 websocket即时通讯 shiro redis
A代码编辑器,在线模版编辑,仿开发工具编辑器,pdf在线预览,文件转换编码 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器 freemaker模版技术 , ...
- 使用tomcat方式实现websocket即时通讯服务端讲解
使用tomcat方式实现websocket即时通讯服务端讲解 第一种方案:使用Tomcat的方式实现 tomcat版本要求:tomcat7.0+.需要支持Javaee7 导入javeee-api的ja ...
- XyTalk企业即时通讯IM开始开源
网址: https://gitee.com/475660/xyTalk-pc https://github.com/xy-Group/xyTalk-pc Xy.Platform是一个高性能.可扩展的企 ...
- java SSM 框架 多数据源 代码生成器 websocket即时通讯 shiro redis 后台框架源码
A 调用摄像头拍照,自定义裁剪编辑头像 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技 ...
- java ssm 后台框架平台 项目源码 websocket 即时通讯 IM quartz springmvc
官网 http://www.fhadmin.org/D 集成安全权限框架shiro Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权,更安全,更可靠E ...
- java SSM 框架 代码生成器 websocket即时通讯 shiro redis
1. 权限管理:点开二级菜单进入三级菜单显示 角色(基础权限)和按钮权限 角色(基础权限): 分角色组和角色,独立分配菜单权限和增删改查权限. 按钮权限: 给角色分配按钮权限. ...
- HTML5+NodeJs实现WebSocket即时通讯
声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 最近都在学习HTML5,做canvas游戏之类的,发现HTML5中除了canvas这个强大的工具外,还有WebSocket也很值得注意.可 ...
随机推荐
- OpenStack 通过某类可用域查找相应虚拟机使用的flavor模板
nova availability-zone-list:列出集群的所有可用域 截取部分结果: 通过可用域上的宿主机找相应的虚拟机 查看命令 通过 nova list --all-tenant --h ...
- java源码解析之String类(一)
String是我们接触最多的类,无论是学习中还是工作中,基本每天都会和字符串打交道,从字符串本身的各种拼接.切片.变形,再到和其他基本数据类型的转换,几乎无时无刻都在使用它,今天就让我们揭开Strin ...
- 【dateFormatSymbols】JAVA特殊日期格式转换
记录:特殊日期格式转换,如将yyyyMMdd转为01MAY2019 public static final String DATE_VIP_FORMAT = "yyyyMMdd"; ...
- 【springBoot】SpringBoot修改启动logo图案
修改boot启动banner logo看到比较好玩,就存一下~ (1)我们在src/main/resources下新建一个banner.txt文件. (2)通过http://patorjk.com/s ...
- 私服 Nexus 的配置 (转)
https://www.cnblogs.com/yuanermen/p/4574473.html 一.概述 1.概要 现在的项目基本都是用Maven来管理工程,这样一来在公司内容搭建一个私服就非常有必 ...
- swoole异步任务数据报表生成
<?php include 'vendor/autoload.php'; class server { private $serv; private $db; /** * [__construc ...
- Spring中AOP相关源码解析
前言 在Spring中AOP是我们使用的非常频繁的一个特性.通过AOP我们可以补足一些面向对象编程中不足或难以实现的部分. AOP 前置理论 首先在学习源码之前我们需要了解关于AOP的相关概念如切点切 ...
- 【Linux】一步一步学Linux——VMware虚拟机三种网络模式详解(07)
目录 00. 目录 01. 虚拟网络连接组件 02. 常见网络连接配置 03. 桥接模式 04. NAT 模式 05. 仅主机模式 06. 自定义模式 07. 附录 00. 目录 @ 01. 虚拟网络 ...
- Linux文件查看及重定向
Linux文件查看及重定向 实验目标: 通过本实验掌握head.tail.cat.more.less等文件查看命令的使用,理解重定向的概念,掌握两种重定向方法的使用. 实验步骤: 1.通过head ...
- Spring MVC源码(一) ----- 启动过程与组件初始化
SpringMVC作为MVC框架近年来被广泛地使用,其与Mybatis和Spring的组合,也成为许多公司开发web的套装.SpringMVC继承了Spring的优点,对业务代码的非侵入性,配置的便捷 ...