553 lines
19 KiB
C#
Raw Normal View History

2024-11-26 13:45:28 +08:00
using MessagePack;
using Newtonsoft.Json;
2024-07-15 10:31:26 +08:00
using StackExchange.Redis;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using YunDa.ISAS.Redis.Configuration;
using YunDa.ISAS.Redis.Factory;
2024-11-26 13:45:28 +08:00
using MessagePack;
using MessagePack.Resolvers;
using System.Diagnostics;
using System.Text;
using MongoDB.Bson;
using Microsoft.AspNetCore.SignalR;
using MessagePack.Formatters;
2024-07-15 10:31:26 +08:00
namespace YunDa.ISAS.Redis.Repositories
{
public class RedisRepository<TEntity, TPrimaryKey> : IRedisRepository<TEntity, TPrimaryKey>
{
private IRedisClientFactory _redisClientFactory;
private IRedisConfiguration _redisConfiguration;
private IDatabase _database;
2024-11-26 13:45:28 +08:00
private ISubscriber _subscriber;
// 全局配置 CompositeResolver
private static readonly MessagePackSerializerOptions options = MessagePackSerializerOptions.Standard
.WithResolver(CompositeResolver.Create(
new IMessagePackFormatter[] { }, // 自定义时间格式化器
new IFormatterResolver[] {
ContractlessStandardResolver.Instance, // 支持无特性标记的类
StandardResolver.Instance
} // 支持有特性标记的类 } // 无特性标记解析器
));
2024-07-15 10:31:26 +08:00
public RedisRepository(IRedisClientFactory redisClientFactory, IRedisConfiguration redisConfiguration)
{
_redisClientFactory = redisClientFactory;
_redisConfiguration = redisConfiguration;
_database = _redisClientFactory.InstanceRedisDatabase();
2024-11-26 13:45:28 +08:00
_subscriber = _redisClientFactory.Subscriber;
2024-07-15 10:31:26 +08:00
JsonSerializerSettings settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
}
2024-11-26 13:45:28 +08:00
2024-07-15 10:31:26 +08:00
public async Task<bool> InsertOrUpdateoneAsync(TEntity entity, string key, TimeSpan? ttl = null)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return false;
}
2024-11-26 13:45:28 +08:00
//_database.KeyDeleteAsync(key.ToString());
2024-07-15 10:31:26 +08:00
var value = GetSerializeObjectString(entity);
if (ttl == null)
{
return await _database.StringSetAsync(key.ToString(), value);
}
2024-11-26 13:45:28 +08:00
return await _database.StringSetAsync(key.ToString(), value, ttl);
}
public async Task<long> PublishAsync(string channel,TEntity entity)
{
2024-12-12 10:25:24 +08:00
2024-11-26 13:45:28 +08:00
var jsonMessage = GetSerializeObjectString(entity); //序列化
var redisChannel = new RedisChannel(channel, RedisChannel.PatternMode.Literal);
// 发布消息
return await _subscriber.PublishAsync(redisChannel, jsonMessage);
2024-07-15 10:31:26 +08:00
}
2024-12-12 10:25:24 +08:00
2024-11-26 13:45:28 +08:00
public event Action<string, TEntity> OnMessageReceived;
// 订阅接口,支持模式匹配
public void Subscribe(string pattern)
2024-07-15 10:31:26 +08:00
{
2024-11-26 13:45:28 +08:00
var redisChannel = new RedisChannel(pattern, RedisChannel.PatternMode.Pattern);
2024-07-15 10:31:26 +08:00
2024-11-26 13:45:28 +08:00
_subscriber.Subscribe(redisChannel, (channel, message) =>
{
// 当收到消息时触发事件
OnMessageReceived(channel,GetDeserialize<TEntity>(message));
});
2024-07-15 10:31:26 +08:00
}
//封装的ListSet
public void ListUpdateAll(string key, List<TEntity> value)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
lock (_database)
{
_database.KeyDelete(key);
//下面的database 是redis的数据库对象.
var batch = _database.CreateBatch();
List<Task> tasks = new List<Task>();
foreach (var single in value)
{
2024-11-26 13:45:28 +08:00
var s = GetSerializeObjectString(single); //序列化
2024-07-15 10:31:26 +08:00
//_database.ListLeftPush(key, s); //要一个个的插入
var task = batch.ListLeftPushAsync(key, s);
tasks.Add(task);
}
batch.Execute();
_database.WaitAll(tasks.ToArray());
}
}
public async Task DeleteHashKeyAsync(string key, Guid id)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
for (int i = 0; i < 3; i++)
{
if (await _database.HashDeleteAsync(key, id.ToString()))
{
return;
}
2024-11-26 13:45:28 +08:00
Task.Delay(1000).Wait();
2024-07-15 10:31:26 +08:00
}
2024-11-26 13:45:28 +08:00
2024-07-15 10:31:26 +08:00
}
public async Task DeleteHashKeiesAsync(string key, List<Guid> ids)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
var RedisValues = new RedisValue[ids.Count];
for (int i = 0; i < ids.Count; i++)
{
RedisValues[i] = ids[i].ToString();
}
await _database.HashDeleteAsync(key, RedisValues);
}
2024-11-26 13:45:28 +08:00
2024-07-15 10:31:26 +08:00
public void ListRightPush(string key, List<TEntity> value)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
lock (_database) {
//下面的database 是redis的数据库对象.
var batch = _database.CreateBatch();
List<Task> tasks = new List<Task>();
foreach (var single in value)
{
2024-11-26 13:45:28 +08:00
var s = GetSerializeObjectString(single); //序列化
2024-07-15 10:31:26 +08:00
tasks.Add(batch.ListRightPushAsync(key, s));
}
batch.Execute();
_database.WaitAll(tasks.ToArray());
}
2024-11-26 13:45:28 +08:00
2024-07-15 10:31:26 +08:00
}
public void ListRightPush(string key, TEntity value)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
2024-11-26 13:45:28 +08:00
2024-07-15 10:31:26 +08:00
//下面的database 是redis的数据库对象.
var batch = _database.CreateBatch();
List<Task> tasks = new List<Task>();
2024-11-26 13:45:28 +08:00
var s = GetSerializeObjectString(value); //序列化
2024-07-15 10:31:26 +08:00
tasks.Add(batch.ListRightPushAsync(key, s));
batch.Execute();
_database.WaitAll(tasks.ToArray());
}
2024-11-26 13:45:28 +08:00
2024-07-15 10:31:26 +08:00
public async Task<long> ListLenghtAsync(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return 0;
}
//下面的database 是redis的数据库对象.
var batch = _database.CreateBatch();
2024-11-26 13:45:28 +08:00
var lenght = batch.ListLengthAsync(key);
2024-07-15 10:31:26 +08:00
batch.Execute();
return await lenght;
}
//封装的ListGet
public List<TEntity> ListGet(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return null;
}
lock (_database)
{
//ListRange返回的是一组字符串对象
//需要逐个反序列化成实体
var vList = _database.ListRange(key);
List<TEntity> result = new List<TEntity>();
foreach (var item in vList)
{
2024-11-26 13:45:28 +08:00
var model = GetDeserialize<TEntity>(item); //反序列化
2024-07-15 10:31:26 +08:00
result.Add(model);
}
return result;
}
2024-11-26 13:45:28 +08:00
}
2024-07-15 10:31:26 +08:00
public async Task<List<TEntity>> ListGetAsync(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return null;
}
//ListRange返回的是一组字符串对象
//需要逐个反序列化成实体
var vList = await _database.ListRangeAsync(key);
List<TEntity> result = new List<TEntity>();
lock (_database)
{
foreach (var item in vList)
{
2024-11-26 13:45:28 +08:00
var model = GetDeserialize<TEntity>(item); //反序列化
2024-07-15 10:31:26 +08:00
result.Add(model);
}
return result;
}
}
public Dictionary<string, TEntity> HashSetGetDicAll(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return null;
}
var result = new Dictionary<string, TEntity>();
lock (_database)
{
var arr = _database.HashGetAll(key);
if (arr != null)
{
foreach (var item in arr)
{
if (!item.Name.IsNullOrEmpty)
{
//var id = new Guid(item.Name.ToString());
2024-11-26 13:45:28 +08:00
var obj = GetDeserialize<TEntity>(item.Value);
2024-07-15 10:31:26 +08:00
result.TryAdd(item.Name, obj);
}
}
}
}
return result;
}
public TEntity HashSetGetOne(string key, Guid id)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return default;
}
var item = _database.HashGet(key, id.ToString());
if (!item.IsNullOrEmpty)
{
2024-11-26 13:45:28 +08:00
var result = GetDeserialize<TEntity>(item); //反序列化
2024-07-15 10:31:26 +08:00
return result;
}
return default;
}
2024-11-26 13:45:28 +08:00
public TEntity HashSetGetOne(string key, string id)
2024-07-15 10:31:26 +08:00
{
if (string.IsNullOrEmpty(key) || _database == null)
{
2024-11-26 13:45:28 +08:00
return default;
2024-07-15 10:31:26 +08:00
}
2024-11-26 13:45:28 +08:00
var item = _database.HashGet(key, id);
if (!item.IsNullOrEmpty)
2024-07-15 10:31:26 +08:00
{
2024-11-26 13:45:28 +08:00
var result = GetDeserialize<TEntity>(item); //反序列化
return result;
2024-07-15 10:31:26 +08:00
}
2024-11-26 13:45:28 +08:00
return default;
}
public async Task<TEntity> HashSetGetOneAsync(string key, string id)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return default;
}
var item =await _database.HashGetAsync(key, id);
if (!item.IsNullOrEmpty)
{
var result = GetDeserialize<TEntity>(item); //反序列化
return result;
}
return default;
2024-07-15 10:31:26 +08:00
}
public async Task<long> ListLeftPushAsync(string key, TEntity entity)
{
if (string.IsNullOrEmpty(key))
{
return 0;
}
2024-11-26 13:45:28 +08:00
var s = GetSerializeObjectString(entity);
2024-07-15 10:31:26 +08:00
if (await _database.ListLengthAsync(key) > int.MaxValue)
{
if (!await _database.KeyDeleteAsync(key))
{
await _database.KeyExpireAsync(key, TimeSpan.FromMilliseconds(10));
2024-11-26 13:45:28 +08:00
}
2024-07-15 10:31:26 +08:00
}
var res = await _database.ListLeftPushAsync(key, s);
return res;
}
public async Task ListRemoveStringAsync(string key, string value, long count = 0)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
2024-11-26 13:45:28 +08:00
return;
2024-07-15 10:31:26 +08:00
}
await _database.ListRemoveAsync(key, value, count);
return;
}
2024-11-26 13:45:28 +08:00
public async Task<TEntity> GetListTailDataAsync(string key)
2024-07-15 10:31:26 +08:00
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return default;
}
if (_database.KeyExists(key))
{
2024-11-26 13:45:28 +08:00
var length = await _database.ListLengthAsync(key);
var res = await _database.ListGetByIndexAsync(key, length - 1);
var entity = GetDeserialize<TEntity>(res);
2024-07-15 10:31:26 +08:00
return entity;
}
return default;
}
2024-11-26 13:45:28 +08:00
public List<TEntity> GetAll()
{
if (_database == null)
{
return null;
}
List<TEntity> entities = new List<TEntity>();
var keys = _database.Multiplexer.GetServer(_database.Multiplexer.GetEndPoints().First()).Keys();
foreach (var item in keys)
{
if (_database.KeyExists(item))
{
var str = _database.StringGet(item);
var entity = GetDeserialize<TEntity>(str);
entities.Add(entity);
}
}
return entities;
}
public async Task<TEntity> GetOneAsync(string key)
2024-07-15 10:31:26 +08:00
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return default;
}
2024-11-26 13:45:28 +08:00
var str = await _database.StringGetAsync(key);
return str.IsNull ? default : GetDeserialize<TEntity>(str);
}
public async Task<bool> InsertOrUpdateOneAsync(TEntity entity, string key, TimeSpan? ttl = null)
{
if (string.IsNullOrEmpty(key) || _database == null)
2024-07-15 10:31:26 +08:00
{
2024-11-26 13:45:28 +08:00
return false;
}
var value = GetSerializeObjectString(entity);
return await _database.StringSetAsync(key, value, ttl);
}
private byte[] GetSerializeObjectString(TEntity entity)
{
return MessagePackSerializer.Serialize(entity, options);
}
private T GetDeserialize<T>(byte[] data)
{
if (data==null || data.Length==0)
{
return default;
}
//string jsonString = Encoding.UTF8.GetString(data);
//return JsonConvert.DeserializeObject<T>(jsonString);
//string hexString = BitConverter.ToString(data);
//Debug.WriteLine(hexString); // 输出12-AB-3C-4D
try
{
var entity = MessagePackSerializer.Deserialize<T>(data, options);
//Debug.WriteLine("MessagePackSerializer success"); // 输出12-AB-3C-4D
2024-07-15 10:31:26 +08:00
return entity;
}
2024-11-26 13:45:28 +08:00
catch (Exception ex)
{
string jsonString = Encoding.UTF8.GetString(data);
Debug.WriteLine("UTF8: " + jsonString); // 输出12-AB-3C-4D
return JsonConvert.DeserializeObject<T>(jsonString);
}
}
public async Task DeleteKeyAsync(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
int count = 0;
while (!await _database.KeyDeleteAsync(key) && count < 5)
{
count++;
await Task.Delay(10);
}
}
public async Task<bool> HashSetUpdateOneAsync(string key, string id, TEntity entity)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return false;
}
var s = GetSerializeObjectString(entity);
return await _database.HashSetAsync(key, id, s);
}
public async Task<bool> HashSetUpdateManyAsync(string key, List<Guid> ids, List<TEntity> entities)
{
if (string.IsNullOrEmpty(key) || _database == null || ids.Count != entities.Count)
{
return false;
}
var hashEntries = ids.Select((id, index) =>
new HashEntry(id.ToString(), GetSerializeObjectString(entities[index]))).ToArray();
await _database.HashSetAsync(key, hashEntries);
return true;
}
public async Task<bool> HashSetUpdateManyAsync(string key, List<string> ids, List<TEntity> entities)
{
if (string.IsNullOrEmpty(key) || _database == null || ids.Count != entities.Count)
{
return false;
}
var hashEntries = ids.Select((id, index) =>
new HashEntry(id, GetSerializeObjectString(entities[index]))).ToArray();
await _database.HashSetAsync(key, hashEntries);
return true;
}
public async Task<List<TEntity>> ListRangeAsync(string key, int start = 0, int stop = -1)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return null;
}
var redisValues = await _database.ListRangeAsync(key, start, stop);
return redisValues
.Select(item => GetDeserialize<TEntity>(item))
.ToList();
}
public async Task<TEntity> ListRightPopAsync(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return default;
}
var res = await _database.ListRightPopAsync(key);
return res.IsNull ? default : GetDeserialize<TEntity>(res);
}
public async Task<List<TEntity>> HashSetGetAllAsync(string key)
{
var hashEntries = await _database.HashGetAllAsync(key);
if (hashEntries.Length == 0)
return default;
List<TEntity> entities = new List<TEntity>();
foreach (var entry in hashEntries)
{
var value = GetDeserialize<TEntity>(entry.Value);
entities.Add(value);
}
return entities;
}
public async Task<TEntity> HashSetGetAllAsync(string key,string hashkey)
{
var hashEntries = await _database.HashGetAsync(key, hashkey);
var value = GetDeserialize<TEntity>(hashEntries);
return value;
}
public async Task<Dictionary<string, TEntity>> HashSetGetDicAllAsync(string key)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return null;
}
var result = new Dictionary<string, TEntity>();
var arr = await _database.HashGetAllAsync(key);
foreach (var item in arr)
{
if (!item.Name.IsNullOrEmpty)
{
var obj = GetDeserialize<TEntity>(item.Value);
result.TryAdd(item.Name, obj);
}
}
return result;
}
public async Task UpdateOneAsync(TEntity entity, string key, TimeSpan? ttl = null)
{
if (string.IsNullOrEmpty(key) || _database == null)
{
return;
}
var data = await _database.StringGetWithExpiryAsync(key);
var s = GetSerializeObjectString(entity);
await _database.StringSetAsync(key, s, data.Expiry ?? ttl);
}
public async Task<bool> KeyExistsAsync(string key)
{
return _database != null && await _database.KeyExistsAsync(key);
2024-07-15 10:31:26 +08:00
}
}
}