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
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);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|