room mgr fix

This commit is contained in:
sin365 2024-09-20 18:27:13 +08:00
parent 2b051b7a27
commit 23db5358fb
6 changed files with 351 additions and 4 deletions

View File

@ -0,0 +1,74 @@
using System.Data;
using System.Text.Encodings.Web;
using System.Text;
using System.Text.Json;
using System.Text.Unicode;
namespace AxibugEmuOnline.Server.Common
{
public class ConfigDataModel
{
public string DBIp{get;set;}
public ushort DBPort{get;set; }
public string DBName { get; set; }
public string DBUname{get;set;}
public string DBPwd{get;set;}
public string RomDir{get;set;}
public string ImageDir { get; set; }
public string ServerIp { get; set; }
public ushort ServerPort { get; set; }
public string ClientVersion { get; set; }
}
public static class Config
{
public static ConfigDataModel cfg;
public static bool LoadConfig()
{
try
{
string path = System.Environment.CurrentDirectory + "//config.cfg";
if (!File.Exists(path))
{
ConfigDataModel sampleCfg = new ConfigDataModel
{
DBIp = "127.0.0.1",
DBPort = 3306,
DBUname = "user",
DBPwd = "password",
DBName = "DBName",
RomDir = "./Rom",
ImageDir = "./Img",
ServerIp = "127.0.0.1",
ServerPort = 10001,
ClientVersion = "0.0.0.1"
};
string jsonString = JsonSerializer.Serialize(sampleCfg, new JsonSerializerOptions()
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
System.IO.File.WriteAllText(path, jsonString, Encoding.UTF8);
Console.WriteLine("未找到配置,已生成模板,请浏览" + path);
return false;
}
StreamReader sr = new StreamReader(path, Encoding.Default);
String jsonstr = sr.ReadToEnd();
cfg = JsonSerializer.Deserialize<ConfigDataModel>(jsonstr);
sr.Close();
return true;
}
catch (Exception ex)
{
Console.WriteLine("配置文件异常:" + ex.ToString());
return false;
}
}
}
}

View File

@ -0,0 +1,178 @@
using MySql.Data.MySqlClient;
namespace AxibugEmuOnline.Server.Common
{
public static class Haoyue_SQLPoolManager
{
private static Queue<MySqlConnection> SQLPool = new Queue<MySqlConnection>();
private static Dictionary<MySqlConnection, Haoyue_PoolTime> _OutOfSQLPool = new Dictionary<MySqlConnection, Haoyue_PoolTime>();
private static Dictionary<string, long> _DicSqlRunFunNum = new Dictionary<string, long>();
private static Dictionary<string, long> _DicTimeOutSqlRunFunNum = new Dictionary<string, long>();
private const int DefaultCount = 1;
private const int MaxLimit = 5;
private static readonly object _sync = new object();
private static MySqlConnectionStringBuilder connBuilder;
public static void InitConnMgr()
{
connBuilder = new MySqlConnectionStringBuilder();
connBuilder.Database = Config.cfg.DBName;
connBuilder.Server = Config.cfg.DBIp;
connBuilder.UserID = Config.cfg.DBUname;
connBuilder.Password = Config.cfg.DBPwd;
connBuilder.Port = Config.cfg.DBPort;
//connBuilder.MinimumPoolSize = 40u;
//connBuilder.MaximumPoolSize = 100u;
connBuilder.Pooling = true;
Console.WriteLine("SQLPool连接初始化....");
for (int i = 0; i < DefaultCount; i++)
{
MySqlConnection _conn = conn();
_conn.Open();
SQLPool.Enqueue(_conn);
}
Console.WriteLine("SQLPool初始化完毕,连接数" + SQLPool.Count);
}
public static MySqlConnection conn()
{
return new MySqlConnection(connBuilder.ConnectionString);
}
public static MySqlConnection DequeueSQLConn(string FuncStr)
{
lock (_sync)
{
if (_DicSqlRunFunNum.ContainsKey(FuncStr))
{
_DicSqlRunFunNum[FuncStr]++;
}
else
{
_DicSqlRunFunNum[FuncStr] = 1L;
}
MySqlConnection _conn;
if (SQLPool.Count < 1)
{
Console.WriteLine("[DequeueSQLConn]创建新的SQLPool.Count>" + SQLPool.Count);
_conn = conn();
_conn.Open();
}
else
{
Console.WriteLine("[DequeueSQLConn]取出一个SQLCount.Count>" + SQLPool.Count);
_conn = SQLPool.Dequeue();
}
_OutOfSQLPool.Add(_conn, new Haoyue_PoolTime
{
time = time(),
FuncStr = FuncStr
});
return _conn;
}
}
public static void EnqueueSQLConn(MySqlConnection BackConn)
{
lock (_sync)
{
if (_OutOfSQLPool.ContainsKey(BackConn))
{
_OutOfSQLPool.Remove(BackConn);
}
else
{
Console.WriteLine("出队遗漏的数据出现了!");
}
if (SQLPool.Count > MaxLimit)
{
Console.WriteLine("已经不需要回收了,多余了,SQLPool.Count>" + SQLPool.Count);
BackConn.Close();
BackConn = null;
}
else
{
SQLPool.Enqueue(BackConn);
Console.WriteLine("回收SQLPool.Count>" + SQLPool.Count);
}
}
}
public static void CheckPoolTimeOut()
{
lock (_sync)
{
long now = time();
List<MySqlConnection> removeTemp = new List<MySqlConnection>();
foreach (KeyValuePair<MySqlConnection, Haoyue_PoolTime> o2 in _OutOfSQLPool)
{
if (now - o2.Value.time >= 120)
{
if (_DicTimeOutSqlRunFunNum.ContainsKey(o2.Value.FuncStr))
{
_DicTimeOutSqlRunFunNum[o2.Value.FuncStr]++;
}
else
{
_DicTimeOutSqlRunFunNum[o2.Value.FuncStr] = 1L;
}
if (SQLPool.Count > MaxLimit)
{
Console.WriteLine("[超时回收]" + o2.Value.FuncStr + "已经不需要回收了,多余了,SQLPool.Count>" + SQLPool.Count);
o2.Key.Close();
}
else
{
Console.WriteLine("[超时回收]" + o2.Value.FuncStr + "回收SQLPool.Count>" + SQLPool.Count);
SQLPool.Enqueue(o2.Key);
}
removeTemp.Add(o2.Key);
}
}
if (removeTemp.Count() <= 0)
{
return;
}
foreach (MySqlConnection o in removeTemp)
{
if (_OutOfSQLPool.ContainsKey(o))
{
_OutOfSQLPool.Remove(o);
Console.WriteLine("[超时回收]_OutOfSQLPool清理");
}
else
{
Console.WriteLine("[超时回收]_OutOfSQLPool清理异常");
}
}
Console.WriteLine("[超时回收]处理结束SQLPool.Count>" + SQLPool.Count);
}
}
public static long time()
{
return Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds);
}
public static void GetPoolState()
{
Console.WriteLine("-----------------查询统计-----------------");
foreach (KeyValuePair<string, long> dic2 in _DicSqlRunFunNum)
{
Console.WriteLine(dic2.Key + ":" + dic2.Value);
}
Console.WriteLine("-----------------超时统计-----------------");
foreach (KeyValuePair<string, long> dic in _DicTimeOutSqlRunFunNum)
{
Console.WriteLine(dic.Key + ":" + dic.Value);
}
Console.WriteLine("------------------------------------------");
}
}
public class Haoyue_PoolTime
{
public long time { get; set; }
public string FuncStr { get; set; }
}
}

View File

@ -1,4 +1,7 @@
namespace AxibugEmuOnline.Server.Common
using System.Security.Cryptography;
using System.Text;
namespace AxibugEmuOnline.Server.Common
{
public static class Helper
{
@ -16,5 +19,20 @@
TimeSpan ts = dt - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds);
}
public static string FileMD5Hash(string filePath)
{
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filePath))
{
var hash = md5.ComputeHash(stream);
var sb = new StringBuilder(hash.Length * 2);
foreach (var b in hash)
sb.AppendFormat("{0:x2}", b);
return sb.ToString();
}
}
}
}
}

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Server.Manager;
using AxibugEmuOnline.Server.Common;
using AxibugEmuOnline.Server.Manager;
using AxibugEmuOnline.Server.NetWork;
using System.Net;
@ -17,6 +18,8 @@ namespace AxibugEmuOnline.Server
public static void InitServer(int port)
{
Config.LoadConfig();
Haoyue_SQLPoolManager.InitConnMgr();
g_Tick = new TickManager();
g_ClientMgr = new ClientManager();
g_ClientMgr.Init(45000, 120);

View File

@ -224,10 +224,13 @@ namespace AxibugEmuOnline.Server
if (joinErrcode == ErrorCode.ErrorOk && bHadRoomStateChange)
SendRoomStateChange(room);
SendRoomUpdateToAll(room.RoomID, 0);
}
public void OnCmdRoomLeave(Socket sk, byte[] reqData)
{
AppSrv.g_Log.Debug($"OnCmdRoomJoin ");
AppSrv.g_Log.Debug($"OnCmdRoomLeave ");
ClientInfo _c = AppSrv.g_ClientMgr.GetClientForSocket(sk);
Protobuf_Room_Leave msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Leave>(reqData);
Protobuf_Room_Leave_RESP resp = new Protobuf_Room_Leave_RESP();
@ -248,6 +251,12 @@ namespace AxibugEmuOnline.Server
if (errcode == ErrorCode.ErrorOk && bHadRoomStateChange)
SendRoomStateChange(room);
SendRoomUpdateToAll(room.RoomID, 1);
if (room.GetPlayerCount() < 1)
RemoveRoom(room.RoomID);
}
public void OnHostPlayerUpdateStateRaw(Socket sk, byte[] reqData)

View File

@ -1,4 +1,6 @@
using AxibugEmuOnline.Server.Manager;
using AxibugEmuOnline.Server.Common;
using AxibugEmuOnline.Server.Manager;
using MySql.Data.MySqlClient;
namespace AxibugEmuOnline.Server
{
@ -62,11 +64,74 @@ namespace AxibugEmuOnline.Server
}
}
break;
case "updatehash":
{
UpdateRomHash();
}
break;
default:
Console.WriteLine("未知命令" + CommandStr);
break;
}
}
}
static void UpdateRomHash()
{
AppSrv.g_Log.Info("UpdateRomHash");
MySqlConnection conn = Haoyue_SQLPoolManager.DequeueSQLConn("UpdateRomHash");
try
{
List<(int id, string romurl, string name)> list = new List<(int id, string romurl, string name)>();
List<(int id, string romurl, string name)> Nonelist = new List<(int id, string romurl, string name)>();
string query = $"SELECT id,`Name`,GameType,Note,RomUrl,ImgUrl,`Hash` FROM romlist_nes";
using (var command = new MySqlCommand(query, conn))
{
// 执行查询并处理结果
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
list.Add(
(reader.GetInt32(0),
!reader.IsDBNull(4) ? reader.GetString(4) : string.Empty,
!reader.IsDBNull(1) ? reader.GetString(1) : string.Empty
));
}
}
}
for (int i = 0; i < list.Count; i++)
{
string rompath = Config.cfg.RomDir + "/" + list[i].romurl;
rompath = System.Net.WebUtility.UrlDecode(rompath);
if (!File.Exists(rompath))
{
Nonelist.Add(list[i]);
continue;
}
string romhash = Helper.FileMD5Hash(rompath);
AppSrv.g_Log.Info($"第{i}个Name->{list[i].name},Hash->{romhash}");
query = $"update romlist_nes SET `Hash` = '{romhash}' where Id ={list[i].id}";
using (var command = new MySqlCommand(query, conn))
{
// 执行查询并处理结果
int reader = command.ExecuteNonQuery();
if (reader > 0)
AppSrv.g_Log.Info($"第{i}个,处理成功");
else
AppSrv.g_Log.Info($"第{i}个,处理失败");
}
}
AppSrv.g_Log.Info($"处理完毕,共{Nonelist.Count}个文件没有找到");
}
catch (Exception e)
{
AppSrv.g_Log.Info($"err:{e.ToString()}");
}
Haoyue_SQLPoolManager.EnqueueSQLConn(conn);
}
}
}