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.
 
 
 
 
 
 

237 lines
8.7 KiB

/*
Sog 游戏基础库
2016 by zouwei
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sog.Gate
{
public sealed class GateService
{
// 和Gate的管理消息
public static void NotifyGateServer(ServerApp app, uint gateServerID, ref GateMsgHeader gateHeader)
{
MessageData message = new MessageData();
message.Header.Length = GateMsgHeaderPacker.GetLength();
message.Header.Type = (int)SpecialMessageType.GateMsgHeaderType;
message.MallocData(GateMsgHeaderPacker.GetLength());
GateMsgHeaderPacker.Pack(ref gateHeader, message.Buffer.Data);
app.GetCluster().Send(gateServerID, message);
}
public static void NotifyGateServerDisconnect(ServerApp app, uint gateServerID, long sessionID)
{
GateMsgHeader gateHeader;
gateHeader.OpCode = (int)GateMsgOpCode.DisconnectedReq;
gateHeader.SessionID = sessionID;
NotifyGateServer(app, gateServerID, ref gateHeader);
}
/// <summary>
/// 注意这个函数内部会调用message.FreeData()
/// </summary>
private static void SendToGate(Cluster cluster, uint gateServerID, long sessionID, MessageData message)
{
GateMsgHeader gateHeader;
gateHeader.OpCode = (int)GateMsgOpCode.Trans;
gateHeader.SessionID = sessionID;
byte[] headerBytes = GateMsgHeaderPacker.Pack(ref gateHeader);
MessageData newMessage = new MessageData();
newMessage.Header.Type = message.Header.Type;
newMessage.Header.Length = message.Header.Length + headerBytes.Length;
newMessage.Header.ObjectID = sessionID;
newMessage.MallocData(newMessage.Header.Length);
Buffer.BlockCopy(headerBytes, 0, newMessage.Buffer.Data, 0, headerBytes.Length);
Buffer.BlockCopy(message.Buffer.Data, 0, newMessage.Buffer.Data, headerBytes.Length, message.Buffer.Length);
message.FreeData();
cluster.Send(gateServerID, newMessage);
}
private static void BroadcastToGate(Cluster cluster, uint gateServerID, List<long> sessionIDs, MessageData message)
{
//有最大值,超过了上层负责分
if(sessionIDs.Count > GateMsgDefine.TransMultiSessionCountMax)
{
TraceLog.Error("GateService.BroadcastToGate too many session count {0}, max {1}"
,sessionIDs.Count,GateMsgDefine.TransMultiSessionCountMax);
return;
}
GateMsgHeader gateHeader;
gateHeader.OpCode = (int)GateMsgOpCode.TransMulti;
gateHeader.SessionID = 0;
GateMsgMultiSessionHeader multiSessionHeader;
multiSessionHeader.Count = sessionIDs.Count;
unsafe{
for(int i=0; i<sessionIDs.Count;i++)
{
multiSessionHeader.SessionIDs[i] = sessionIDs[i];
}
}
byte[] headerBytes = GateMsgHeaderPacker.Pack(ref gateHeader,ref multiSessionHeader);
MessageData newMessage = new MessageData();
newMessage.Header.Type = message.Header.Type;
newMessage.Header.Length = message.Header.Length + headerBytes.Length;
newMessage.MallocData(newMessage.Header.Length);
Buffer.BlockCopy(headerBytes, 0, newMessage.Buffer.Data, 0, headerBytes.Length);
Buffer.BlockCopy(message.Buffer.Data, 0, newMessage.Buffer.Data, headerBytes.Length, message.Buffer.Length);
message.FreeData();
cluster.Send(gateServerID, newMessage);
}
//通知gate接下来的消息转发给新的逻辑服务器,有可能带上一个新消息
public static void RouteBackEndServer(Cluster cluster, uint gateServerID, long sessionID, MessageData message, uint newLogicServerID)
{
GateMsgHeader gateHeader;
gateHeader.OpCode = (int)GateMsgOpCode.Route;
gateHeader.SessionID = sessionID;
byte[] headerBytes = GateMsgHeaderPacker.Pack(ref gateHeader);
MessageData newMessage = new MessageData();
newMessage.Header.Type = message.Header.Type;
newMessage.Header.Length = message.Header.Length + headerBytes.Length;
newMessage.Header.ObjectID = sessionID;
newMessage.Header.ServerID = newLogicServerID;
newMessage.MallocData(newMessage.Header.Length);
Buffer.BlockCopy(headerBytes, 0, newMessage.Buffer.Data, 0, headerBytes.Length);
Buffer.BlockCopy(message.Buffer.Data, 0, newMessage.Buffer.Data, headerBytes.Length, message.Buffer.Length);
message.FreeData();
cluster.Send(gateServerID, newMessage);
}
public static void SendToGate<T>(long uid, Cluster cluster, uint gateServerID, long sessionID, int iMsgID, ref T packet)
where T : struct, ProtoCSStruct.IStructMessage<T>
{
MessageData messageData = new MessageData();
messageData.Header.Type = iMsgID;
messageData.Header.ObjectID = sessionID;
//不打印ping
if (TraceLog.IsSkipLogMsgID(iMsgID) == false)
{
//是否打印到player日志
if (uid > 0 && TraceLog.NeedLogUserTraceLevel(uid))
{
TraceLog.UserTraceDetail(uid, "GateService.SendToGate uid {0} msgId {1} iID {2} message:{3}->{4}"
, uid
, iMsgID
, sessionID
, packet.GetName()
, packet.ToString());
}
else
{
//预先判断,提高效率
if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail)
{
TraceLog.TraceDetail("GateService.SendToGate uid {0} msgId {1} iID {2} message:{3}->{4}"
, uid
, iMsgID
, sessionID
, packet.GetName()
, packet.ToString());
}
}
}
bool bRet = ProtoPackerFactory.Instance.GetProtoCSStructPacker().PackMessage(ref packet, ref messageData);
if (bRet == false)
{
TraceLog.Error("GateService.SendToGate PackMessage error");
return;
}
if (uid < 1000 && uid > 0)
{
TraceLog.Error("GateService.SendToGate Do Not Send UID {0}",uid);
// 这是伪造的测试账号, 不用发给gate
}
else
{
SendToGate(cluster, gateServerID, sessionID, messageData);
}
}
public static void BroadcastToGate<T>(long uid, Cluster cluster, uint gateServerID, List<long> sessionIDs, int iMsgID, ref T packet)
where T : struct, ProtoCSStruct.IStructMessage<T>
{
MessageData messageData = new MessageData();
messageData.Header.Type = iMsgID;
//不打印ping
if (TraceLog.IsSkipLogMsgID(iMsgID) == false)
{
//是否打印到player日志
if (uid > 0 && TraceLog.NeedLogUserTraceLevel(uid))
{
TraceLog.UserTraceDetail(uid, "GateService.SendToGate uid {0} msgId {1} iID {2} message:{3}->{4}"
, uid
, iMsgID
, 0
, packet.GetName()
, packet.ToString());
}
else
{
//预先判断,提高效率
if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail)
{
TraceLog.TraceDetail("GateService.SendToGate uid {0} msgId {1} iID {2} message:{3}->{4}"
, uid
, iMsgID
, 0
, packet.GetName()
, packet.ToString());
}
}
}
bool bRet = ProtoPackerFactory.Instance.GetProtoCSStructPacker().PackMessage(ref packet, ref messageData);
if (bRet == false)
{
TraceLog.Error("GateService.SendToGate PackMessage error");
return;
}
BroadcastToGate(cluster, gateServerID, sessionIDs, messageData);
}
}
}