分享利用 redis 订阅与发布特性, 巧妙的现实高性能 im 系统. 为表诚意, 先贴源码地址: https://github.com/2881099/im
下载源码后的运行方法:
运行环境:.NETCore 2.1 + redis-server 2.8
下载 Redis-x64-2.8.2402.zip, 点击 start.bat 运行; 或者修改 imServer,web 下面 appsettings.json redis 配置, 指向可用的 redis-server
- cd imServer && dotnet run --urls="http://0.0.0.0:6001/"
- cd web && dotnet run --urls="http://0.0.0.0:5555/"
打开多个浏览器, 访问 http://127.0.0.1:5555/ 发送群消息
https://github.com/2881099/im#设计思路 设计思路
https://github.com/2881099/im#socket选型 socket 选型
最二的办法是浏览器端使用 websocket, 其他端 socket, 这么混乱的设计最终将非常难维护.
所以强烈建议所有端都使用 websocket 协议, adorid/ios/h5 / 小程序全部支持 websocket 客户端.
https://github.com/2881099/im#业务与通讯协议 业务与通讯协议
im 系统一般涉及[我的好友] ,[我的群] ,[历史消息] 等等..
那么, imServer 与业务方 (web) 该保持何种关系呢?
用户 A 向好友 B 发送消息, 分析一下:
需要判断 B 是否为 A 好友;
需要判断 A 是否有权限;
等等..
诸如此类业务判断会很复杂, 我们试想一下, 如果使用 imServer 做业务协议, 它是不是会变成巨无霸难以维护.
又假如获取历史记录, 难道客户端要先 websocket.send('gethistory'), 再在 onmessage 里定位回调处理?
这样做十分之二...
咱这样设计, 所有用户的主动行为走业务方(web),imServer 只负责即时消息推送. 什么意思?
用户 A 向好友 B 发送消息: 客户端请求业务方 (web) 接口, 由业务方 (web) 后端向 imServer 发起推送请求, imServer 收到指令后, 向前端用户 B 的 websocket 发送数据, 用户 B 收到了消息.
获取历史消息: 客户端请求业务方 (web) 接口, 返回 json(历史消息)
回执: 用户 A 如何知道消息发送状态(成功或失败或不在线)?imServer 端向用户 B 发送消息时, 把状态以消息的方式推给用户 A 即可(按上面的逻辑), 具体请看源码吧...
https://github.com/2881099/im#web通知imserver性能优化 web 通知 imServer 性能优化
采用消息队列, redis 的发布订阅最为轻量.
https://github.com/2881099/im#实现多节点部署 实现多节点部署
单个 imServer 实例支持多少 websocket 连接, 几百个没问题吧, 好...
如果系统在线用户有 1 万人, 怎么办???
可以根据 id 的 hash 分区, 比如部署 4 个 imServer:
imServer1 订阅 redisChanne1
imServer2 订阅 redisChanne2
imServer3 订阅 redisChanne3
imServer4 订阅 redisChanne4
业务方 (web) 端根据接收方的 id 的 hash 分区算法, 定位到对应的 redisChannel, 这样 publish 就可以将消息定位到相应的 imServer 了
来源: https://www.cnblogs.com/kellynic/p/9286645.html