服务器的配置分了三个文件:分别是ChannelConfig.xml、HotFixConfig.xml、ServerConfig.xml。
ChannelConfig.xml 标签中的属性
ChannelId: 渠道Id
InnerVersion: 内部版本号
SourceVersion: 该渠道当前的资源版本号(根据当前的资源版本号和资源地址拼接出一个绝对路径)
SourceUrl: 资源站点的Ip和端口
RechargeUrl: 充值服务器的地址
PayServerNo: 充值服务器编号
TDAppId: 统计平台编号
IsOpenTD: 是否开启统计
Xml配置
ChannelConfig.cs代码解析加载ChannelConfig.xml。使用了System.Xml.Linq的XDocument工具类来加载xml文件。其基本原理就是获取到Root节点下名为“Channel”的所有Element节点,然后使用迭代器循环,拿到每一个Element中的属性,先缓存ChannelEntity结构中,最后存到字典里。
namespace Servers.Common
{
public class ChannelConfig
{
public static Dictionary m_dicChannel;
//渠道数据初始化
public static void Init()
{
m_dicChannel = new Dictionary();
string path = AppDomain.CurrentDomain.BaseDirectory + "Configs/ChannelConfig.xml";
ChannelEntity entity;
XDocument doc = XDocument.Load(path);
XElement item;
IEnumerator iter = doc.Root.Elements("Channel").GetEnumerator();
for (; iter.MoveNext();)
{
item = iter.Current;
entity = new ChannelEntity();
int.TryParse(item.Attribute("ChannelId").Value,out entity.ChannelId);
int.TryParse(item.Attribute("InnerVersion").Value,out entity.InnerVersion);
entity.SourceVersion = item.Attribute("SourceVersion").Value;
entity.SourceUrl = item.Attribute("SourceUrl").Value;
entity.RechargeUrl = item.Attribute("RechargeUrl").Value;
int.TryParse(item.Attribute("PayServerNo").Value, out entity.InnerVersion);
entity.TDAppId = item.Attribute("TDAppId").Value;
bool.TryParse(item.Attribute("IsOpenTD").Value,out entity.IsOpenTD);
//频道Id_内部版本
m_dicChannel[entity.ChannelId + "_" + entity.InnerVersion] = entity;
}
Console.WriteLine(" ChannelConfig Load Complete");
}
}
}
HotFixConfig.xml中的属性
Key:Dll名字 Value:Dll文件名
Xml配置。热更新dll名称配置表格的原因是每次加载的时候都需要把名字往后+1,C#不允许加载相同名字的Dll
HotFixConfig.cs代码解析加载HotFixConfig.xml。
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
namespace Servers.Common
{
//可以热更新的配置文件
public class HotFixConfig
{
private static Dictionary m_dicParams;
//根据Key获取参数
public static string GetParams(string key)
{
string value = null;
m_dicParams.TryGetValue(key,out value);
return value;
}
//加载热更新dll参数
public static void Load()
{
//有可能会重复Load,所以每次Load需要Clear操作
if (null == m_dicParams)
m_dicParams = new Dictionary();
else
m_dicParams.Clear();
//cs工程目录+Configs目录,拼接出来一个绝对目录
string path = AppDomain.CurrentDomain.BaseDirectory + "Configs/HotFixConfig.xml";
XElement item;
XDocument doc = XDocument.Load(path);
IEnumerator iter = doc.Root.Elements("Item").GetEnumerator();
for (; iter.MoveNext();)
{
item = iter.Current;
string key = item.Attribute("Key").Value;
string value = item.Attribute("Value").Value;
m_dicParams[key] = value;
}
Console.WriteLine(" HotFixConfig Load Complete");
}
}
}
ServerConfig.xml 标签中的属性
AreaServerId: 区服编号
CurrServerType: 当前服务器类型
CurrServerId: 当前服务器编号
MongoConnectString: MongoDB连接字符串
RedisConnectString: Redis连接字符串
DataTablePath: 数据表路径
Servers: 服务器配置
Xml配置,这个是按照单服的结构设计的xml,如果以后有多服了,得把Servers、DB、Redis都得移到AreaServer里面去,外面套一层结构
1
0
0
mongodb://127.0.0.1
127.0.0.1:6379
C:\game\Server\Release\DataTable
>
>
>
>
>
>
ServerConfig.cs代码解析加载ServerConfig.xml。SceneConfig结构存的是哪些服务器应该为哪些场景提供服务器的信息,一个服务器可能算量有限并不能为整个大区的提供计算,将场景为单位把玩家划分到了不同的服务器上进行计算。Server类存的是单个服务器的配置,这个服务器需要开启的场景列表信息。ServerConfig则是有点像是传统的Manager类,会记录所有的Server信息到map结构里。
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using Servers.Core;
namespace Servers.Common
{
public class SceneConfig
{
//场景编号
public int SceneId;
//服务器编号
public int ServerId;
//AOI区域数据路径
public string AOIJsonDataPath;
}
//单台服务器配置
public class Server
{
//服务器类型
public ConstDefine.ServerType CurrServerType;
//服务器编号
public int ServerId;
//服务器Ip
public string Ip;
//服务器端口
public int Port;
//这个服务器需要开启的场景列表(这个服务器为特定的一些场景提供服务,跳转场景则切另一个服务器为玩家服务)
public List SceneConfigs { get; }
public Server()
{
SceneConfigs = new List(100);
}
}
public class ServerConfig
{
#region 静态成员
//区服编号
public static int AreaServerId;
//当前服务器类型
public static ConstDefine.ServerType CurrServerType;
//当前服务器编号
public static int CurrServerId = 0;
//Mongo连接字符串
public static string MongoConnectionString;
//Redis连接字符串
public static string RedisConnectionString;
//数据表路径
public static string DataTablePath;
//区服内服务器列表
private static List ServerList;
//场景和游戏服务器的对应字典(哪个场景在哪个服务器上运算 SceneId:SceneConfig)
public static Dictionary DicSceneInServer;
//游戏服务DB名(一个区服务,一个DB??一个区服如果只使用一个DB,很多个服务同时像这一个DB写数据的话不会造成拥堵吗??)
private static string m_GameServerDBName = null;
public static string GameServerDBName
{
get
{
if (string.IsNullOrEmpty(m_GameServerDBName))
m_GameServerDBName = string.Format("GameServer_{0}", AreaServerId);
return m_GameServerDBName;
}
}
//角色HashKey(就是个Key,看代码好像是一个区服只能有一个Role啊,目前没看到哪里用)
private static string m_RoleHashKey = null;
private static string RoleHashKey
{
get
{
if (string.IsNullOrEmpty(m_RoleHashKey))
m_RoleHashKey = string.Format("{0}_RoleHash", AreaServerId);
return m_RoleHashKey;
}
}
//角色昵称Key(玩家名称)
private static string m_RoleNickNameKey = null;
public static string RoleNickNameKey
{
get
{
if (string.IsNullOrEmpty(m_RoleNickNameKey))
m_RoleNickNameKey = string.Format("{0}_NickName", AreaServerId);
return m_RoleNickNameKey;
}
}
public static void Init()
{
string path = AppDomain.CurrentDomain.BaseDirectory + "Configs/ServerConfig.xml";
XDocument doc = XDocument.Load(path);
XElement itemRoot = doc.Root;
AreaServerId = itemRoot.Element("AreaServerId").Value.ToInt();
CurrServerType = (ConstDefine.ServerType)itemRoot.Element("CurrServerType").Value.ToInt();
CurrServerId = itemRoot.Element("CurrServerId").Value.ToInt();
MongoConnectionString = itemRoot.Element("MongoConnectString").Value;
RedisConnectionString = itemRoot.Element("RedisConnectString").Value;
DataTablePath = itemRoot.Element("DataTablePath").Value;
ServerList = new List();
DicSceneInServer = new Dictionary();
//初始化服务器节点
XElement itemServer;
IEnumerator iterServer = itemRoot.Element("Servers").Elements("Item").GetEnumerator();
for (; iterServer.MoveNext();)
{
itemServer = iterServer.Current;
ServerList.Add(new Server()
{
CurrServerType = (ConstDefine.ServerType)itemServer.Attribute("ServerType").Value.ToInt(),
ServerId = itemServer.Attribute("ServerId").Value.ToInt(),
Ip = itemServer.Attribute("Ip").Value,
Port = itemServer.Attribute("Port").Value.ToInt()
}) ;
}
//初始化场景对应的服务器
XElement itemScene;
SceneConfig sceneCfg;
Server server;
int sceneId;
int serverId;
string aoiJsonDataPath;
IEnumerator iterScene = itemRoot.Element("Scenes").Elements("Item").GetEnumerator();
for (; iterScene.MoveNext();)
{
itemScene = iterScene.Current;
sceneId = itemScene.Attribute("SceneId").Value.ToInt();
serverId = itemScene.Attribute("ServerId").Value.ToInt();
aoiJsonDataPath = itemScene.Attribute("AOIJsonDataPath").Value;
sceneCfg = new SceneConfig()
{
SceneId = sceneId,
ServerId = serverId,
AOIJsonDataPath = aoiJsonDataPath
};
//保存场景对应的服务器
DicSceneInServer[sceneId] = sceneCfg;
//获取对应的服务器,正向写入该服务器会服务哪些场景
server = GetServer(ConstDefine.ServerType.GameServer, serverId);
if (null != server)
{
server.SceneConfigs.Add(sceneCfg);
}
}
Console.WriteLine("ServerConfig Init Complete");
}
public static Server GetServer(ConstDefine.ServerType type,int serverId)
{
int iLen = ServerList.Count;
Server server = null;
for (int i = 0; i < iLen; ++i)
{
server = ServerList[i];
if (server.CurrServerType == type && server.ServerId == serverId)
return server;
}
return null;
}
#endregion
}
}
这个笔记写完啦!