首页 > 代码库 > 号召大伙完善一个IM系统---------C#+JS (二)-------服务端封装Redis
号召大伙完善一个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的味道? 但是这里的跨库事务是不支持的,因为上下文是按库来进行创建的,每一个库都有它自己对应的上下文)
号召大伙完善一个IM系统---------C#+JS (二)-------服务端封装Redis