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.
175 lines
5.8 KiB
175 lines
5.8 KiB
/*
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|