You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.8 KiB

1 month ago
/*
Sog
2016 by zouwei
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Sog;
using Sog.Gate;
namespace Gate
{
// 客户端连接的路由策略,可定制一定路由规则
public class ServerRoute : BaseReloadableService
{
private ServerApp m_app;
private long m_selectBackEndSeq = 0;
//接口实现
public override int GetServiceType()
{
return GateServiceType.ServerRoute;
}
//接口实现
public override void Dispose()
{
m_app = null;
}
public ServerRoute(ServerApp app)
{
m_app = app;
}
/// <summary>
/// 选择后端逻辑服务器
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public uint SelectBackEndServerID(GateClientInfo info)
{
//如果之前已经有了,直接采用
if(info.LinkServerID != 0)
{
return info.LinkServerID;
}
//随机选一个
int backEndType = GateServerUtils.GetServerConfig().backEndServerType;
uint[] serverIDs = m_app.GetCluster().GetRemoteAppID(backEndType);
if(serverIDs.Length == 0)
{
TraceLog.Error("ServerRoute.SelectBackEndServerID no valid logic server id, serverType {0}", backEndType);
return 0;
}
uint serverId = 0;
int myType = ServerIDUtils.GetServerType(m_app.ServerID);
int myInstId = (int)ServerIDUtils.GetInstanceID(m_app.ServerID);
//游戏服务器尽量选instid相同的,这样保证第一次选择就是正确的game,不用切
if (myType == (int)ServerType.GameGate && myInstId <= serverIDs.Length)
{
serverId = serverIDs[myInstId - 1];
}
else
{
int index = (int)(m_selectBackEndSeq % serverIDs.Length);
serverId = serverIDs[index];
m_selectBackEndSeq++;
}
TraceLog.Trace("SelectBackEndServerID SelectPlayerGameGate myInstId {0} serverId {1}", myInstId, ServerIDUtils.IDToString(serverId));
info.LinkServerID = serverId;
return info.LinkServerID;
}
public void RouteBackEndServer(uint remoteAppID, MessageData message, GateMsgHeader header)
{
GateClientInfo info = GateServerUtils.GetGateClientService().GetGateClientInfoThreadSafe(header.SessionID);
if (info == null)
{
TraceLog.Debug("ServerRoute.RouteBackEndServer session {0} message ,but can not find session,drop msg"
, header.SessionID);
return;
}
if (info.State != GameClientState.Noraml)
{
TraceLog.Debug("ServerRoute.RouteBackEndServer session {0} message ,but session stat is {1},drop msg"
, header.SessionID, GameClientState.Noraml);
return;
}
uint routeServerID = message.Header.ServerID;
TraceLog.Debug("ServerRoute.RouteBackEndServer session {0} src server {1} change to dst server {2}"
, header.SessionID, ServerIDUtils.IDToString(remoteAppID), ServerIDUtils.IDToString(routeServerID));
//判断下route的目标服务器合不合法
int backEndType = GateServerUtils.GetServerConfig().backEndServerType;
uint[] serverIDs = m_app.GetCluster().GetRemoteAppID(backEndType);
bool valid = false;
foreach (uint serverId in serverIDs)
{
if (serverId == routeServerID)
{
valid = true;
break;
}
}
if (valid == false)
{
TraceLog.Error("ServerRoute.RouteBackEndServer session {0} message ,but route serverid invalid {1}"
, header.SessionID, routeServerID);
return;
}
//改后端服务器地址
info.LinkServerID = routeServerID;
string ip = "0.0.0.0";
if (info.Session != null && info.Session.RemoteEndPoint != null)
{
try
{
ip = info.Session.RemoteEndPoint.ToString().Split(':')[0];
}
catch (Exception)
{
}
}
//先通知一个connected
GateClientConnectedReq req = new GateClientConnectedReq();
req.IPAddress = ip;
GateServerUtils.GetServerMsgTrans().NotifyServerClientConnected(info, req);
//转发消息,判断一下是不是有实际消息需要转发,没有就算了
if (message.Header.Length > GateMsgHeaderPacker.GetLength())
{
TraceLog.Debug("ServerRoute.RouteBackEndServer session {0} trans route msg to new server"
, header.SessionID);
//这里面本来是GateMsgOpCode.Route,直接改成Trans就可以了
GateMsgHeaderPacker.RawSetGateMsgHeadOpCode(message.Buffer.Data, GateMsgOpCode.Trans);
//拷贝一个新的,要不然内存管理会出问题
MessageData newMessage = new MessageData();
newMessage.Header = message.Header;
newMessage.MallocData(message.Buffer.Length);
Buffer.BlockCopy(message.Buffer.Data, 0, newMessage.Buffer.Data, 0, newMessage.Buffer.Length);
m_app.GetCluster().Send(info.LinkServerID, newMessage);
}
}
}
}