Files
hjha-server/GameDAL/db/redis/redisManager.cs
xiaoou e9616125ce feat: initial commit - HJHA game server full source
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
2026-07-07 12:02:15 +08:00

453 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 由SharpDevelop创建。
* 用户: Administrator
* 日期: 2018-09-14
* 时间: 15:16
*
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
*/
using System;
using StackExchange.Redis;
using System.Collections.Generic;
using MrWu.Debug;
using System.Linq;
using GameData;
using Server.Config;
namespace Server.DB.Redis
{
/// <summary>
/// 数据库类型
/// </summary>
public enum DbStyle
{
/// <summary>
/// 主库
/// </summary>
main,
/// <summary>
/// 比赛
/// </summary>
bisai
}
/// <summary>
/// redis数据库管理
/// </summary>
public class redisManager
{
/* redis 命令大全
* del key 删除键
* dump key 序列化key 返回序列化的值
* exists key 检查key是否存在
* exipire key seconds 设置过期的时间
* pexipire key milliseconds 设置过期时间毫秒
* keys keyspattem 查找给定格式的key
* move key db 将key移动到给定数据库db中
* persist key 移除key的过期时间
* pttl key 返回剩余过期时间以毫秒计
* ttl key 返回剩余的过期时间以秒计
* randomkey 随机返回一个key
* rename key newkey 修改key的名称
* renamenx key newkey 仅当newkey不存在时将key改名为newkey
* type key 返回key所存储的值类型
*
* 字符串类型的命令
* set key value 设置key 字符串值
* get key 获取key的字符串值
* getrange key start end 获取key的字符串一段值
* getset key value 从新设置key的值 并返回原来的值
* getbit key offset ------
* strlen key 返回key存储的字符串长度
* mset key1 value1 key2 value2 设置一个或多个字符串的值
* msetnx key1 value1 key2 value2 设置一个活多个字符串的值不如果存在key则不设置
* setex key seconds value 将值value关联到key,并将key的过期时间设为seconds秒
* psetex key millseconds value 将value关联到key并将key的过期时间设为milliseconds毫秒
* incr key 将key中存储的数字值增一 只能value是整数才能使用 并返回存储后的值
* incrby key increment 将key中存储的数字值增加increment 并返回存储后的值
* incrbyfloat key increment 将key中存储的数字值增加increment的浮点值 并返回存储后的值 存在误差
* decr key 将key中存储的数字减一 只有value是数字型的时候才能使用 并返回存储后的值
* decrby key decrement 将key中存储的数字值减少decrement 并返回存储后的值
* append key value 如果key已经存在并且是一个字符串 append 命令将指定的value追加到key原来的值的末尾 并返回追加后的字符串长度
*
* hash类型的命令
* hmset key hashkey1 value1 hashkey2 vlaue2 将新的hash字段插入到hash表中
* hget key hashkey 获取hash中的key
* hdel key hashkey1 hashkey2 删除一个或多个hash字段
* hexists key filed 查询哈希表中是否存在filed
* hgetall key 获取在哈希表中指定的key的所有字段和值
* hincrby key field increment 为哈希表中key 的值增加1
* hincrbyfloat key field increment 为哈希表中key 的值浮点值增量
* hkeys key 获取所有的哈希表中key值
* hlen key 获取哈希表中字段的数量
* hmget key field1 field2 获取给定字段的值
* hset key field vlaue 如果hash表中存在key则 修改key的值 如果不存在则添加
* hsernx key filed value 只有在hash表中不存在field字段时才设置值
* hvals key 获取hash表中的所有值
*
* List 列表类型命令
* lpush key value1 value2 将值插入到key列表中的头部
* blpop key key1 timeout 优先取key中的值如果key中有值返回第一个值 如果key中没有值取key1中的值 如果key1也没有值 则会等待timeout后超时
* brpop key key1 timeout 获取最后一个值
* brpoplpush source destination timeout 从source 中取出一个值并插入到destination 中 如果没有值知道timeout才停止
* lindex key index 通过索引获取表中的元素
* linsert key before value
* lpop key 移出并获取列表中的第一个元素
* lpush key value1 value2 将值插入到已存在key列表中的头部
* lpushx key value 将一个值插入到已存在key表中的头部
* lrange key start end 获取列表中指定范围的内的元素
* lrem key count value count>0表示从头向尾搜索移除value相等的元素 数量为count count<0表示从尾巴向头搜索移除value相等的元素 数量为count的绝对值 count = 0 时移除列表中所有的value相等的元素
* lset key index value 设置列表index上的值
* ltrim key satrt stop 指定列表保留的元素区间,不在区间内的元素将会被删除
* rpop key 移除并获取列表中的最后一个元素\
* rpoplpush source destination 移除source中的最后一个元素并将该元素添加到destination表中
* rpush key value1 value2 将值插入到列表的尾部
* rpushx key value 向已存在的表中添加值
*
* Set 集合命令
* sadd key menber1 menber2 向集合中添加一个或多个成员
* scard key 获取集合中的成员数量
* sdiff key key1 返回所有集合的差集
* sdiffstore destination key key1 返回给定所有集合的差集 并存储到destination 中
* sinter key key1 缩回所有集合的交集
* sindterstore destination key key1 返回所有集合的交集 并存储到destination中
* sismember key member 判断member元素是否是集合key的成员
* smemers key 返回集合中的所有成员
* smove source destination member 将member元素从source集合移动到destination集合中
* spop key 移除并返回集合中的一个随机元素
* srandmember key count 返回集合中的一个或多个随机元素
* serm key member member1 移除集合中的一个或多个成员
* sunion key key1 返回所有给定集合的并集
* sunionstore destination key1 key2 返回所有给定集合的并集并存储在destination集合中
* 迭代集合中的元素xxxx
*
* 有序集合
* zadd key score member1 socre1 member2 向有序集合添加一个或多个成员,或者更新已存在的成员的分数
* zcard key 获取有序集合的成员数量
* zcount key min max 计算在有序集合中指定区间分数的成员数
* zincrby key increment member 有序集合中对指定成员的分数加增量increment
* ---zinterstore destination numkeys key key1
* --zlexcount key min max 在有序集合中计算指定字典区间内成员数量
*
*
*
*
*
* */
/**
* 通配符 * 表示任意一个或多个字符
* ? 表示任意字符
* [abc] 表示方括号中任意一个字母
*
* */
private redisManager()
{
}
/// <summary>
/// 主redis 数据库连接
/// </summary>
private static RedisConnectionHelp mainDBConnection;
/// <summary>
/// 比赛redis 数据库连接
/// </summary>
private static RedisConnectionHelp bisaiDBConnection;
private static volatile bool isStart = false;
/// <summary>
/// redis操作数据库代理_逻辑数据库处理
/// </summary>
public static IDatabaseProxy db
{
get
{
if (isStart)
{
return new IDatabaseProxy(mainDBConnection.Instance.GetDatabase());
}
return null;
}
}
/// <summary>
/// redis 操作数据库代理_逻辑数据库处理
/// </summary>
/// <param name="idx"></param>
/// <returns></returns>
public static IDatabaseProxy Getdb(int idx)
{
if (isStart)
return new IDatabaseProxy(mainDBConnection.Instance.GetDatabase(idx));
return null;
}
/// <summary>
/// 获取比赛数据库处理
/// </summary>
/// <param name="idx"></param>
/// <returns></returns>
public static IDatabaseProxy GetBiSaidb(int idx = -1)
{
if (isStart)
return new IDatabaseProxy(bisaiDBConnection.Instance.GetDatabase(idx));
return null;
}
/// <summary>
/// 获取数据库操作
/// </summary>
/// <returns></returns>
public static IDatabase GetDataBase(DbStyle sty = DbStyle.main, int idx = -1)
{
ConnectionMultiplexer cm = null;
switch (sty)
{
case DbStyle.main:
cm = mainDBConnection.Instance;
break;
case DbStyle.bisai:
cm = bisaiDBConnection.Instance;
break;
}
if (cm == null)
return null;
return cm.GetDatabase(idx);
}
public static List<RedisKey> Keys(string pattern, int dbidx, int pageSize = 1000, DbStyle sty = DbStyle.main)
{
if (!isStart) return null;
ConnectionMultiplexer cm = null;
switch (sty)
{
case DbStyle.main:
cm = mainDBConnection.Instance;
break;
case DbStyle.bisai:
cm = bisaiDBConnection.Instance;
break;
}
if (cm == null)
return null;
List<RedisKey> allkeys = new List<RedisKey>();
try
{
var points = cm.GetEndPoints();
if (points.Length < 1)
{
Debug.Error("redis 没有任何连接!");
return null;
}
IServer server = cm.GetServer(points[0]);
if (points.Length > 1)
{
ClusterConfiguration clusternodes = server.ClusterNodes();
foreach (var item in clusternodes.Nodes)
{
if (!item.IsSlave)
{
IServer temp = cm.GetServer(item.EndPoint);
IEnumerable<RedisKey> rks = temp.Keys(dbidx, pattern,pageSize);
foreach (RedisKey rk in rks)
{
allkeys.Add(rk);
}
}
}
}
else
{
var rks = server.Keys(dbidx, pattern, pageSize);
foreach (var key in rks)
{
allkeys.Add(key);
}
}
}
catch (Exception e)
{
Debug.Error("查询错误asdsahdjk" + e.ToString());
return allkeys;
}
return allkeys;
}
/// <summary>
/// 启动redis 服务器
/// </summary>
/// <param name="AllowAdmin">管理员模式</param>
public static void Start(bool AllowAdmin = false)
{
for (int i = 0; i < RedisConfigCategory.Instance.DataList.Count; i++)
{
var item = RedisConfigCategory.Instance.DataList[i];
switch (item.Name)
{
case "main":
mainDBConnection = new RedisConnectionHelp();
mainDBConnection.Start(item, AllowAdmin);
break;
case "bisai":
bisaiDBConnection = new RedisConnectionHelp();
bisaiDBConnection.Start(item, AllowAdmin);
break;
}
}
isStart = true;
}
}
/// <summary>
/// ConnectionMultiplexer对象管理帮助类__单例换多例
/// </summary>
public class RedisConnectionHelp
{
private readonly object Locker = new object();
private ConnectionMultiplexer _instance;
/// <summary>
/// 单例获取
/// </summary>
public ConnectionMultiplexer Instance
{
get
{
if (_instance == null)
{
lock (Locker)
{
if (_instance == null || !_instance.IsConnected)
{
//Debug.Error("获取新的实例!!!!");
_instance = GetManager();
}
}
}
return _instance;
}
}
RedisConfig redisConfig;
bool AllowAdmin;
/// <summary>
/// 启动redis
/// </summary>
/// <param name="redisConfig_"></param>
/// <param name="AllowAdmin_"></param>
public void Start(RedisConfig redisConfig_, bool AllowAdmin_ = false)
{
redisConfig = redisConfig_;
AllowAdmin = AllowAdmin_;
}
private ConnectionMultiplexer GetManager(string connectionString = null)
{
ConfigurationOptions options = new ConfigurationOptions();
options.ConnectTimeout = redisConfig.ConnectTimeOut;
options.AllowAdmin = AllowAdmin;
options.AbortOnConnectFail = false; //true 表示连接失败将不会创建链接实例
options.ConnectRetry = 5; //失败尝试重新链接的次数
options.EndPoints.Add(redisConfig.Host, redisConfig.Port);
ConnectionMultiplexer cml = ConnectionMultiplexer.Connect(options);
//redisPool.TimeoutMilliseconds = 3000;
cml.ConnectionFailed += MuxerConnectionFailed;
cml.ConnectionRestored += MuxerConnectionRestored;
cml.ErrorMessage += MuxerErrorMessage;
cml.ConfigurationChanged += MuxerConfigurationChanged;
cml.HashSlotMoved += MuxerHashSlotMoved;
cml.InternalError += MuxerInternalError;
return cml;
}
#region
/// <summary>
/// 配置更改时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
{
Debug.Fatal("Configuration changed: " + e.EndPoint);
}
/// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
{
Debug.Fatal("ErrorMessage: " + e.Message);
}
/// <summary>
/// 重新建立连接之前的错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
Debug.Fatal("ConnectionRestored: " + e.EndPoint);
}
/// <summary>
/// 连接失败 如果重新连接成功你将不会收到这个通知
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
Debug.Fatal("重新连接Endpoint failed: " + e.EndPoint + ", " + e.FailureType +
(e.Exception == null ? "" : (", " + e.Exception.Message)));
}
/// <summary>
/// 更改集群
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
Debug.Fatal("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
}
/// <summary>
/// redis类库错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MuxerInternalError(object sender, InternalErrorEventArgs e)
{
Debug.Fatal("InternalError:Message" + e.Exception.Message);
}
#endregion
}
}