6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
309 lines
10 KiB
C#
309 lines
10 KiB
C#
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 {
|
|
/// <summary>
|
|
/// 缓存管理
|
|
/// </summary>
|
|
public class CaCheManager {
|
|
|
|
private CaCheManager() {
|
|
}
|
|
|
|
static CaCheManager() {
|
|
instance = new CaCheManager();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 实例
|
|
/// </summary>
|
|
public static CaCheManager instance {
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
private IDatabase DB {
|
|
get {
|
|
return redisManager.GetDataBase(DbStyle.main, RedisDictionary.cachedb);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 缓 key 对应 缓存的key Tuple('版本','数据')
|
|
/// </summary>
|
|
ConcurrentDictionary<string, Tuple<long, string>> caches = new ConcurrentDictionary<string, Tuple<long, string>>();
|
|
|
|
/// <summary>
|
|
/// 获取缓存
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Tuple<long, string> GetCache(string key) {
|
|
|
|
Tuple<long, string> 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<Tuple<long, string>> UpdateKeyAsync(string key)
|
|
{
|
|
return Task.Run(() => UpdateKey(key));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新缓存_也就是把Redis中的数据读取到内存中来
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
public Tuple<long, string> UpdateKey(string key) {
|
|
|
|
Debug.Info("更新缓存" + key);
|
|
var type = redisManager.Getdb(RedisDictionary.cachedb).KeyType(key);
|
|
|
|
Tuple<long, string> result = null;
|
|
Tuple<long, string> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取hash
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
Tuple<long, string> 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<JObject>(keyvalues[i].Value);
|
|
}
|
|
//Debug.Info("获取到缓存:" + key + ":" + verResult);
|
|
JObject baseobj = new JObject();
|
|
baseobj["ver"] = verResult;
|
|
baseobj["data"] = obj;
|
|
return new Tuple<long, string>(value, JsonPack.GetJson(baseobj));
|
|
} else
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取字符串
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
Tuple<long, string> 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<long, string>(ver, JsonPack.GetJson(baseobj));
|
|
} else
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取列表
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
Tuple<long, string> 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<JObject>(values[i]));
|
|
}
|
|
|
|
JObject baseobj = new JObject();
|
|
baseobj["ver"] = ver;
|
|
baseobj["data"] = jar;
|
|
|
|
return new Tuple<long, string>(ver, JsonPack.GetJson(baseobj));
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查版本是否达到了最大
|
|
/// </summary>
|
|
/// <param name="verKey">版本key</param>
|
|
/// <param name="task">增加版本的任务</param>
|
|
private void CheckVerMax(string verKey, Task<long> task) {
|
|
if (task.Result > 9999999999) {
|
|
DB.StringSet(verKey, 1);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除缓存
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
public bool DelCache(string key) {
|
|
var tran = DB.CreateTransaction();
|
|
tran.KeyDeleteAsync(key);
|
|
tran.KeyDeleteAsync(key + ":ver");
|
|
return tran.Execute();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设Hash缓存数据
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="field"></param>
|
|
/// <param name="value"></param>
|
|
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("保存配置失败!");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除缓存的Hash字段
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="field"></param>
|
|
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("删除配置失败!");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置字符串类型的缓存
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
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("保存配置失败!");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 列表形式的缓存 下次再拓展
|
|
*
|
|
*
|
|
* */
|
|
|
|
/// <summary>
|
|
/// 发送缓存变化包
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
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();
|
|
}
|
|
|
|
|
|
}
|
|
}
|