using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Server.DB.Redis; using System.Collections.Concurrent; using MrWu.Debug; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using StackExchange.Redis; using Server.Pack; using Server.MQ; using GameData; namespace Server { /// /// 缓存管理 /// public class CaCheManager { private CaCheManager() { } static CaCheManager() { instance = new CaCheManager(); } /// /// 实例 /// public static CaCheManager instance { get; private set; } private IDatabase DB { get { return redisManager.GetDataBase(DbStyle.main, RedisDictionary.cachedb); } } /// /// 缓 key 对应 缓存的key Tuple('版本','数据') /// ConcurrentDictionary> caches = new ConcurrentDictionary>(); /// /// 获取缓存 /// /// public Tuple GetCache(string key) { Tuple result = null; if (!caches.TryGetValue(key, out result)) { //缓存没有值 result = UpdateKey(key); } if (result == null && !caches.TryGetValue(key, out result)) { Debug.Warning("没这个缓存数据:" + key); } Debug.Log("获取到缓存!" + result); return result; } public Task> UpdateKeyAsync(string key) { return Task.Run(() => UpdateKey(key)); } /// /// 更新缓存_也就是把Redis中的数据读取到内存中来 /// /// public Tuple UpdateKey(string key) { Debug.Info("更新缓存" + key); var type = redisManager.Getdb(RedisDictionary.cachedb).KeyType(key); Tuple result = null; Tuple value = null; switch (type) { case StackExchange.Redis.RedisType.Hash: value = GetHash(key); //转换成 json ver,data={字典} 字典传输出去 break; case StackExchange.Redis.RedisType.String: value = GetString(key); //转换成 json ver,data={字符串} break; case StackExchange.Redis.RedisType.List: value = GetList(key); //转换成 json ver,data={数组} break; } if (!string.IsNullOrEmpty(key)) { result = caches.AddOrUpdate(key, value, (k, v) => value); } //Debug.Info($"得到缓存:{value}"); return result; } /// /// 获取hash /// /// /// Tuple GetHash(string key) { var tran = DB.CreateTransaction(); var keyvaluestask = tran.HashGetAllAsync(key); //拿数据 var valuestask = tran.StringGetAsync(key + ":ver"); //拿版本 if (tran.Execute()) { if (keyvaluestask.Result == null || keyvaluestask.Result.Length == 0) return null; var keyvalues = keyvaluestask.Result; long value = -1; string verResult = valuestask.Result; if (verResult != null && !long.TryParse(verResult, out value)) { Debug.Warning("未获取到版本号!" + key); value = -1; } JObject obj = new JObject(); int len = keyvalues.Length; for (int i = 0; i < len; i++) { obj[keyvalues[i].Name] = JsonPack.GetData(keyvalues[i].Value); } //Debug.Info("获取到缓存:" + key + ":" + verResult); JObject baseobj = new JObject(); baseobj["ver"] = verResult; baseobj["data"] = obj; return new Tuple(value, JsonPack.GetJson(baseobj)); } else return null; } /// /// 获取字符串 /// /// /// Tuple GetString(string key) { var tran = DB.CreateTransaction(); var valuetask = tran.StringGetAsync(key); var vertask = tran.StringGetAsync(key + ":ver"); if (tran.Execute()) { long ver = -1; string verResult = vertask.Result; if (verResult != null && !long.TryParse(verResult, out ver)) { Debug.Warning("未获取到版本号!" + key); ver = -1; } JObject baseobj = new JObject(); baseobj["ver"] = ver; baseobj["data"] = (string)valuetask.Result; return new Tuple(ver, JsonPack.GetJson(baseobj)); } else return null; } /// /// 获取列表 /// /// /// Tuple GetList(string key) { var tran = DB.CreateTransaction(); var valuestask = tran.ListRangeAsync(key); var vertask = tran.StringGetAsync(key + ":ver"); if (tran.Execute()) { var values = valuestask.Result; if (values == null || values.Length == 0) return null; long ver = -1; string verResult = vertask.Result; if (verResult != null && !long.TryParse(verResult, out ver)) { Debug.Warning("未获取到版本号!" + key); ver = -1; } JArray jar = new JArray(); int len = values.Length; for (int i = 0; i < len; i++) { jar.Add(JsonPack.GetData(values[i])); } JObject baseobj = new JObject(); baseobj["ver"] = ver; baseobj["data"] = jar; return new Tuple(ver, JsonPack.GetJson(baseobj)); } else { return null; } } /// /// 检查版本是否达到了最大 /// /// 版本key /// 增加版本的任务 private void CheckVerMax(string verKey, Task task) { if (task.Result > 9999999999) { DB.StringSet(verKey, 1); } } /// /// 删除缓存 /// /// public bool DelCache(string key) { var tran = DB.CreateTransaction(); tran.KeyDeleteAsync(key); tran.KeyDeleteAsync(key + ":ver"); return tran.Execute(); } /// /// 设Hash缓存数据 /// /// /// /// public void SetHash(string key, string field, string value) { var tran = DB.CreateTransaction(); tran.HashSetAsync(key, field, value); string verKey = key + ":ver"; var taskVer = tran.StringIncrementAsync(verKey); Debug.Info($"保存缓存数据:{field} {value}"); if (tran.Execute()) { Debug.Log("保存Hash缓存成功!" + value); CheckVerMax(verKey, taskVer); } else { Debug.Error("保存配置失败!"); } } /// /// 删除缓存的Hash字段 /// /// /// public void DelHashField(string key, string field) { var tran = DB.CreateTransaction(); tran.HashDeleteAsync(key, field); string verKey = key + ":ver"; var taskVer = tran.StringIncrementAsync(verKey); if (tran.Execute()) { Debug.Log("删除Hash子段成功!"); CheckVerMax(verKey, taskVer); } else { Debug.Error("删除配置失败!"); } } /// /// 设置字符串类型的缓存 /// /// /// public void SetString(string key, string value) { var tran = DB.CreateTransaction(); tran.StringSetAsync(key, value); string verKey = key + ":ver"; var taskVer = tran.StringIncrementAsync(verKey); if (tran.Execute()) { Debug.Log("设置string缓存成功!" + value); CheckVerMax(verKey, taskVer); } else { Debug.Error("保存配置失败!"); } } /* * 列表形式的缓存 下次再拓展 * * * */ /// /// 发送缓存变化包 /// /// public static void SendCacheChange(string key) { PackHead head = PackHead.Create(ServerPackAgreement.CacheChange); head.otherString = new string[] { key }; Debug.Log("发送更新缓存包:"); GlobalMQ.instance.DeliveryAll(GlobalMQ.CreateMessage(head, null), true); head.Dispose(); } } }