ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理

摘要:
privateOnlineUserCurrentOnlineUser{get{returnnewOnlineUser}connectionid=CurrentConnectId;userid=CurrentUserId};

前言

  上篇的预告好像是“聊天室的小细节,你都注意到了吗?”。今天也是为那篇做铺垫吧。之前的版本有好多问题,比如:当前登录用户是否合法问题,userid参数如果随便传后台没有验证。还有一个致命的问题,用户AB都在线,但是如果A没有打开B的窗口或者B没有打开A的窗口,那么发消息,对方是收不到的。因为他们没有进入到同一个组里面。本篇讲述了一些Redis的东西。由于项目本身就是为了学习和练习一些东西。所以,Redis并不是我的强项,只不过随便研究研究,具体专业的用法我也不太会。还在学习中。。。

实现思路

  首先,我采用了Redis中的哈希表结构来存储用户的在线信息。如下图所示:key代表userid,value是用户的connectionid

  ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理第1张

  是不是很简单,那么存储这些数据有什么好处呢,

  1.我们可以统计多少在线用户

  2.配合前端界面,实现某个好友是否在线

  3.判断好友是否在线在决定是否像该好友推送消息(不在线的话,直接存储离线消息就可以)

  4.解决前言中存在的问题。对于这个问题详细解释一下,比如A给B发消息,A点击打开了B的窗口,现在A已经加入到组AB中。但是B不在组AB中,所以,B收不到本组的消息。假如A打开B窗口的时候,判断一下A是否在线,如果A在线,那么将A加入到AB组中,也就是多了一步 A=》Group的操作。这样的话,就解决了AB不同组导致收不到消息的问题。详细看下图:

  ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理第2张

实现细节

  我们只要在Hub代码中的建立连接,失去连接,重新连接的方法中添加对当前用户的操作逻辑就可以。

  /// <summary>
        /// 获取当前用户信息
        /// </summary>
        private OnlineUser CurrentOnlineUser
        {
            get
            {
                return new OnlineUser
                {
                    connectionid = CurrentConnectId,
                    userid = CurrentUserId
                };
            }
        }
        /// <summary>
        /// 建立连接
        /// </summary>
        /// <returns></returns>
        public override Task OnConnected()
        {
            //将当前用户添加到redis在线用户缓存中
            LayIMCache.Instance.OperateOnlineUser(CurrentOnlineUser);
            return Clients.Caller.receiveMessage("连接成功");
        }
        /// <summary>
        /// 失去连接
        /// </summary>
        /// <param name="stopCalled"></param>
        /// <returns></returns>
        public override Task OnDisconnected(bool stopCalled)
        {
            //将当前用户从在线用户列表中剔除
            LayIMCache.Instance.OperateOnlineUser(CurrentOnlineUser, isDelete: true);
            return Clients.Caller.receiveMessage("失去连接");
        }

        /// <summary>
        /// 重新连接
        /// </summary>
        /// <returns></returns>
        public override Task OnReconnected()
        {
            //将当前用户添加到redis在线用户缓存中
            LayIMCache.Instance.OperateOnlineUser(CurrentOnlineUser);
            return Clients.Caller.receiveMessage("重新连接");
        }

  这里我用的.NET客户端是 StackExchange.Redis.Extensions.Core  ,他其实是在 StackExchange.Redis的基础上有一层封装。用起来更方便一些,喜欢直接用  StackExchange.Redis 的也没问题。

  详细代码如下:

      
        static NewtonsoftSerializer serializer = new NewtonsoftSerializer();
        StackExchangeRedisCacheClient cacheClient = new StackExchangeRedisCacheClient(serializer);
        #region 在线用户处理
        public void OperateOnlineUser(OnlineUser user, bool isDelete = false)
        {
            if (isDelete)
            {
                cacheClient.HashDelete(LayIMConst.LayIM_All_OnlineUsers, user.userid);
            }
            else
            {
                cacheClient.HashSetAsync(LayIMConst.LayIM_All_OnlineUsers, user.userid, user.connectionid);
            }
        }
        #endregion

  当我们刷新页面的时候,会先调用 OnDisconnected 方法,在调用 OnConnected 方法。不过,HashSet方法如果是同一个key,可以覆盖其值。

  本篇就到这里了,界面上没有改动,只不过增加了一些基于redis缓存的逻辑。

  GitHub:https://github.com/fanpan26/LayIM_NetClient  喜欢的话给一个star吧,谢谢啦。

  交流群:145322742

免责声明:文章转载自《ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇计算pi的精度+进度条显示信息检索导论学习笔记 --第一章 布尔检索下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

工单系统的设计与实现(2)

本项目后端采用的是SpringBoot+Mybatis进行开发,为REST风格。前端采用的Vue.js框架,组价使用的是Element。数据库使用的是Mysql。部署采用的是nginx+docker。 本博客只用于记录开发思路,具体的实现细节可参考本人的GitHub。  数据库的表结构实现细节省略。  首先,利用IDE创建Spring项目,我使用的是I...

写壳1

写壳的步骤 编写加壳器,加载被加壳程序和壳dll程序 将 dll 程序中 .text 拷贝到被加壳程序 将被加壳程序的 eip 指向stub 代码 需要让 stub 提供一个入口点 1. 加载 PE 文件5. 加载 Stub 文件 8. 加载共享数据,写入了原始OE篇2. 添加了一个区段4. 实现了一个 stub 提供了 start 7...

TCP的socket资源被耗尽的问题

一、 故障现象 部分机顶盒用户出现大面积登录APP时,界面停留在登陆页面,无反应。 二、 现象初步分析 本次问题出现时,所有AAA出现了异常流量波动,在AAA异常流量段期间接到用户故障报障。此时主要表现在LVS集群显示真实的EPG 服务器不停的被踢出集群和加入(UP/DOWN),导致了用户调度到EPG后出现了异常显示。 AAA异常流量图 三、 问题排查过...

操作系统-数据库知识点查漏学习一

一.自陷和中断的主要区别?答:1. 中断(zhong duan)(1) 是由由CPU外部产生的,对CPU来说,是被动的。(2) 当中断发生时,CPU将下一条指令,也就是接下来要执行的指令的地址压入栈作为中断服务的返回地址。 2. 陷入 (xian ru)(1) 是由CPU本身在执行程序过程中产生的。它是由专设的指令,如X86中的“INT n”,在程序中有意...

[学习笔记]云计算扫盲

 个人小站,正在持续整理中,欢迎访问:http://shitouer.cn 小站博文地址:[学习笔记]云计算扫盲 何为云计算?最简单最形象的一句话:Anyone, anytime, anywhere, any channel, with any devices, accessing any services. Forrester对云计算的定义:A stan...

Mybatis-第N篇配置log4j1、log4j2打印执行的sql语句

1、log4j1配置    目录结构:       conf.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/myba...