• 号召大伙完善一个IM系统---------C#+JS (二)-------服务端封装Redis


    这个IM的服务端,使用的是Redis作为数据库

    我一开始使用的redis的SDK是ServiceStack.Redis,但是据说它是收费的,测试版的一个小时内只能发送1000个请求??

    后来,我改成使用StackExchange.Redis作为Sdk,并根据它的特点进行了一些封装。下面,介绍一下 为什么这样封装以及封装的内容。

    我们先看一下封装后,是如何调用的(最终的目的就是要这样)

    使用关系型数据库(mysql,sqlserver..)时,我们都是有一个DAL层的,dal层的每个类,对应的是一张表,类里的方法,则是这张表的增删该查。

    redis这个非关系型数据库,它不存在表这个概念,它只有一个库的概念。我刚接触redis,我喜欢把这个库当作是sqlserver中的一张表来理解。

    但是redis存储数据使用的是key,value结构,所以我没办法按照以前的分层方式,建一个dal层,对每个库的操作进行封装。虽然可以这么做,但这样是不值得的。

    操作redis类的封装,应该按照操作类型来(增,删,改,查),所以应该封装这几个类(Add,Delete,Update,Get),这里我们把update去掉。这里不需要update。redis会对相同的key进行赋值时,覆盖它的value,没有update一小个部分的做法。

    我封装出来的是这样的(OpretionBase这个类,是他们的父类,父类记录的是通用的上下文

           

    OpretionBase中的上下文,全都是StackExchange.Redis中的定义。 IServer用于库的概况查询,ITransaction用于事务性操作,IDatabase用于一般性操作。

    下面介绍一下最后一个类:OpretionPublic类(只有它向外部提供调用,这边我没办法对应上某个设计模式,只能贴个图,你们自己理解。但是外部调用很简单)

     public class OpretionPublic : IDisposable
        {
            //不要多次实例化这个类,不然会有bug的
            private static readonly ConnectionMultiplexer _client = ConnectionMultiplexer.Connect(Config.Config.redisHost);
          
            private static IServer _server = _client.GetServer(Config.Config.redisIP, Config.Config.redisPort);
            private static List<OpretionPublic> _options = new List<OpretionPublic>();
    
            private static object obj = new object();
            //redis的数据库的没有名称,只能通过一个数字去描述它
            public static OpretionPublic getOperation(int db)
            {
                Monitor.Enter(OpretionPublic.obj);
                var op = _options.FirstOrDefault(o => o._db == db);
                if (op != null)
                {
                    Monitor.Exit(OpretionPublic.obj);
                    return op;
                }
                else
                {
                    var newop = new OpretionPublic(db);
                    _options.Add(newop);
                    Monitor.Exit(OpretionPublic.obj);
                    return newop;
                }
            }
    
            public Add Add { get; set; }
            public Delete Delete { get; set; }
            public Get Get { get; set; }
    
            private ITransaction _tran;
            private int _db { get; set; }
            internal OpretionPublic(int db)
            {
                _db = db;
                var database = _client.GetDatabase(db);
                _tran = database.CreateTransaction();
                Add = new Add(database, _tran, _server);
                Delete = new Delete(database, _tran, _server);
                Get = new Get(database, _tran, _server);
            }
    
            void IDisposable.Dispose()
            {
                //Add.Dispose();
                //Delete.Dispose();
                //Get.Dispose();
            }
    
            public void commitTran()
            {
                _tran.Execute();
            }
    
        }

    现在展示一下外部如何去调用(这样的调用方式是不是有ef的味道? 但是这里的跨库事务是不支持的,因为上下文是按库来进行创建的,每一个库都有它自己对应的上下文)

  • 相关阅读:
    git删除目录,且保留本地的
    gitpush 免密码
    git常用操作
    ubuntu安装Nodejs
    ubuntu如何配置samba
    用AI将png转成svg做字符图标教程
    windows server 2012设置远程连接断开后自动注销
    windows 2012执行计划任务错误:操作员或系统管理员拒绝了请求(0x800710E0)
    删除节点
    代理 XP”组件已作为此服务器安全配置的一部分被关闭。系统管理员可以使用 sp_configure 来启用“代理 XP”。
  • 原文地址:https://www.cnblogs.com/xiaoleye/p/6784205.html
Copyright © 2020-2023  润新知