using System; using System.Collections.Generic; using System.Collections.Concurrent; using ProtoCSStruct; namespace Sog { /// /// 消息发送器,结构体版本 /// public class StructPacketSender { private uint m_serverID; // cluster层有完整的主备2组服务器, 需要确定当前连的是哪组服务器 private uint m_realmlistServerID; private uint m_OperationServerID; private uint m_versionServerID; private uint m_httpProxyPayServerID; private uint m_PlayerOpServerID; // world层 private uint m_worldServerID; private int m_friendSvrNum; private uint m_friendSvrBaseID; private uint m_httpProxyWorldServerID; private int m_battleSvrNum; private uint m_battleSvrBaseID; private uint m_chatServerID; //这个先支持一个 private uint m_rankServerID; //这个先支持一个 private uint m_nameServerID; //这个先支持一个 private uint m_mailServerID;//这个类似world,现在只有一个 private Cluster m_cluster; public StructPacketSender() { } /// /// 初始化,支持线程安全可选项,默认不支持多线程 /// /// /// /// public void Init(uint serverID, Cluster cluster, int clusterInstId = 0) { m_cluster = cluster; m_serverID = serverID; bool isClusterSvr = ServerIDUtils.IsClusterServer(serverID); int svrType = ServerIDUtils.GetServerType(serverID); int instId = (int)ServerIDUtils.GetInstanceID(serverID); // 为了减少改动, 提前暴露问题, 对cluster层的连接简单做如下处理 // cluster层服务器根据instId相连 if (isClusterSvr) { m_realmlistServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.RealmsList, instId); m_httpProxyPayServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.HttpProxyPay, instId); // operation和所有version连, 不能直接调用SendToVersion接口 if (svrType != (int) ServerType.Operation) { m_versionServerID = ServerIDUtils.GetLevel0ServerIDByType((int) ServerType.Version, instId); } } else if (svrType == (int)ServerType.World) { m_realmlistServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.RealmsList, clusterInstId); m_httpProxyPayServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.HttpProxyPay, clusterInstId); } m_OperationServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Operation, 1); m_PlayerOpServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.PlayerOp, 1); // world m_worldServerID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.World, 1); m_chatServerID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.Chat, 1); m_rankServerID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.Rank, 1); m_mailServerID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.Mail, 1); // 好友服务器数量 if (ServerIDUtils.GetServerType(serverID) == (int)ServerType.Friend) { // 加上app自己 m_friendSvrNum = cluster.GetChannelCount((int)ServerType.Friend) + 1; } else { m_friendSvrNum = cluster.GetChannelCount((int)ServerType.Friend); } // 好友服务器基础id m_friendSvrBaseID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.Friend, 0); m_httpProxyWorldServerID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.HttpProxy, 1); m_battleSvrBaseID = ServerIDUtils.GetLevel1ServerIDByType(m_serverID, (int)ServerType.Battle, 0); // 战斗服务器数量 if (ServerIDUtils.GetServerType(serverID) == (int)ServerType.Battle) { // 加上app自己 m_battleSvrNum = cluster.GetChannelCount((int)ServerType.Battle) + 1; } else { m_battleSvrNum = cluster.GetChannelCountInWorld(ServerIDUtils.GetWorldID(m_serverID), (int)ServerType.Battle); } m_nameServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Name, 1); } public uint GetBattleServerBaseID() { return m_battleSvrBaseID; } public uint GetOperationServerIDServerID() { return m_OperationServerID; } public uint GetPlayerOpServerIDServerID() { return m_PlayerOpServerID; } public uint GetMailServerID() { return m_mailServerID; } public void SendToNameServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_nameServerID, iMsgID, ref structMessage, iObjectID, headserverID); } public void SendToVersionServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_versionServerID, iMsgID, ref structMessage, iObjectID, headserverID); } public void SendToFriendServer(StructPacket packet, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { if (m_friendSvrNum == 0) { return; } uint instId = (uint)(iObjectID % m_friendSvrNum); if (instId == 0) { instId = (uint)m_friendSvrNum; } uint friendSvrId = m_friendSvrBaseID + instId; SendToServerByID(friendSvrId, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } public void SendToFriendServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { if (m_friendSvrNum == 0) { return; } uint instId = (uint)(iObjectID % m_friendSvrNum); if (instId == 0) { instId = (uint)m_friendSvrNum; } uint friendSvrId = m_friendSvrBaseID + instId; SendToServerByID(friendSvrId, iMsgID, ref structMessage, iObjectID, headserverID); } public void SendToWorldServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_worldServerID, iMsgID, ref structMessage, iObjectID, headserverID); } public void SendToOperationServer(StructPacket packet, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_OperationServerID, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } public void SendToPlayerOpServer(StructPacket packet, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_PlayerOpServerID, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } public void SendToPlayerOpServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_PlayerOpServerID, iMsgID, ref structMessage, iObjectID, headserverID); } /// /// cluster层向多个World发消息 /// /// /// /// /// /// /// public void SendToWorldServerBymWorldIds(int iMsgID, ref T structMessage, long iObjectID, int[] WorldIds, uint headserverID = 0) where T : struct, IStructMessage { foreach (var WorldId in WorldIds) { var worldServerID = ServerIDUtils.MakeServerID(WorldId, (int)ServerType.World, 1); SendToServerByID(worldServerID, iMsgID, ref structMessage, iObjectID, headserverID); } } public void SendToMailServerBymWorldIds(int iMsgID, ref T structMessage, long iObjectID, int[] WorldIds, uint headserverID = 0) where T : struct, IStructMessage { foreach (var WorldId in WorldIds) { var mailServerID = ServerIDUtils.MakeServerID(WorldId, (int)ServerType.Mail, 1); SendToServerByID(mailServerID, iMsgID, ref structMessage, iObjectID, headserverID); } } public void SendToWorldServer(StructPacket packet, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_worldServerID, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } public void SendToRankServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_rankServerID, iMsgID, ref structMessage, iObjectID, headserverID); } public void SendToRankServer(StructPacket packet, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_rankServerID, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } public void SendToChatServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_chatServerID, iMsgID, ref structMessage, iObjectID, headserverID); } #region 以下方法都是要废弃的,battleServerID 和 gameServerID 都不唯一了,全部废弃 全部废弃 全部废弃 //battle修改下,一定要playerSession //public void SendToBattleServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) // where T : struct, IStructMessage //{ // if (m_battleSvrNum == 0) // { // return; // } // uint instId = (uint)(iObjectID % m_battleSvrNum); // if (instId == 0) // { // instId = (uint)m_battleSvrNum; // } // uint battleSvrId = m_battleSvrBaseID + instId; // SendToServerByID(battleSvrId, iMsgID, ref structMessage, iObjectID, headserverID); // SendToServerByID(TransBattleIDToBattleServerID(battleID), iMsgID, ref structMessage, iObjectID, headserverID); //} //public void SendToBattleServer(StructPacket packet, long iObjectID, uint headserverID = 0) // where T : struct, IStructMessage //{ // if (m_battleSvrNum == 0) // { // return; // } // uint instId = (uint)(iObjectID % m_battleSvrNum); // if (instId == 0) // { // instId = (uint)m_battleSvrNum; // } // uint battleSvrId = m_battleSvrBaseID + instId; // SendToServerByID(battleSvrId, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); // //SendToServerByID(TransBattleIDToBattleServerID(battleID), packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); //} #endregion public void SendToMailServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_mailServerID, iMsgID, ref structMessage, iObjectID, headserverID); } /// /// 转发消息,注意,这个StructPacket请尽量不要自己new!!! /// /// /// public void SendToServerByID(uint dstserverID, StructPacket packet) where T : struct, IStructMessage { SendToServerByID(dstserverID, packet.MsgID, ref packet.GetMessage(), packet.ObjectID, packet.ServerID); } public void SendToServerByID(uint dstserverID, StructPacket packet, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(dstserverID, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } private MessageData PackMessagePrintf(uint dstserverID, int iMsgID, ref T structMessage, long iObjectID, uint headserverID) where T : struct, IStructMessage { MessageData messageData = new MessageData(); messageData.Header.Type = iMsgID; messageData.Header.ObjectID = iObjectID; messageData.Header.ServerID = headserverID; //cache memory bool bRet = ProtoPackerFactory.Instance.GetProtoCSStructPacker().PackMessage(ref structMessage, ref messageData); if (bRet == false) { //判断是不是sessionid,sessionid是个很大的数 if (Sog.Service.GateSessionID.IsGateSessionIDOrUserID(iObjectID)) { TraceLog.Error("PackMessagePrintf error server {0} msgId {1} iID {2} message:{3}" , ServerIDUtils.IDToString(dstserverID), iMsgID, iObjectID , structMessage.GetName()); } else { TraceLog.UserError(iObjectID, "PackMessagePrintf error server {0} msgId {1} iID {2} message:{3}" , ServerIDUtils.IDToString(dstserverID), iMsgID, iObjectID , structMessage.GetName()); } return messageData; } //预先判断,提高效率 if (TraceLog.GetLogLevel() <= Log.LogLevel.TraceDetail) { //不打印详细信息 if(TraceLog.IsSkipLogMsgID(iMsgID)) { //判断是不是sessionid,sessionid是个很大的数 if (Sog.Service.GateSessionID.IsGateSessionIDOrUserID(iObjectID)) { TraceLog.TraceDetail("PackMessagePrintf send to server {0} msgId {1} iID {2} message: {3}" , ServerIDUtils.IDToString(dstserverID), iMsgID, iObjectID , structMessage.GetName()); } else { TraceLog.UserTraceDetail(iObjectID, "PackMessagePrintf send to server {0} msgId {1} iID {2} message: {3}" , ServerIDUtils.IDToString(dstserverID), iMsgID, iObjectID , structMessage.GetName()); } } else//打印详细信息 { //判断是不是sessionid,sessionid是个很大的数 if (Sog.Service.GateSessionID.IsGateSessionIDOrUserID(iObjectID)) { TraceLog.TraceDetail("PackMessagePrintf send to server {0} msgId {1} iID {2} message: {3} ->{4}" , ServerIDUtils.IDToString(dstserverID), iMsgID, iObjectID , structMessage.GetName() , structMessage.ToString()); } else { TraceLog.UserTraceDetail(iObjectID, "PackMessagePrintf send to server {0} msgId {1} iID {2} message: {3} ->{4}" , ServerIDUtils.IDToString(dstserverID), iMsgID, iObjectID , structMessage.GetName() , structMessage.ToString()); } } } return messageData; } public void SendToServerByID(uint dstserverID, int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { MessageData messageData = PackMessagePrintf(dstserverID, iMsgID, ref structMessage, iObjectID, headserverID); if (messageData.Buffer.Data == null) { return; } m_cluster.Send(dstserverID, messageData); } //直接发送MessageData public void SendToServerByID(uint dstserverID, MessageData messageData) { m_cluster.Send(dstserverID, messageData); } public void Broadcast(int serverType, int iMsgID, ref T structMessage, long iObjectID, uint headserverID) where T : struct, IStructMessage { uint serverID = (uint)(serverType << 8); MessageData message = PackMessagePrintf(serverID, iMsgID, ref structMessage, iObjectID, headserverID); if (message.Buffer.Data == null) { return; } m_cluster.Broadcast(serverType, message); } public void Broadcast(int serverType, StructPacket packet) where T : struct, IStructMessage { uint serverID = (uint)(serverType << 8); MessageData message = PackMessagePrintf(serverID, packet.MsgID, ref packet.GetMessage(), packet.ObjectID, packet.ServerID); if (message.Buffer.Data == null) { return; } m_cluster.Broadcast(serverType, message); } public void SendToHttpProxyWorldServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_httpProxyWorldServerID, iMsgID, ref structMessage, iObjectID, headserverID); } public void SendToHttpProxyPayServer(StructPacket packet) where T : struct, IStructMessage { SendToServerByID(m_httpProxyPayServerID, packet.MsgID, ref packet.GetMessage(), packet.ObjectID); } public void SendToRealmlistServer(StructPacket packet, long iObjectID, uint headserverID) where T : struct, IStructMessage { SendToServerByID(m_realmlistServerID, packet.MsgID, ref packet.GetMessage(), iObjectID, headserverID); } public void SendToRealmlistServer(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0) where T : struct, IStructMessage { SendToServerByID(m_realmlistServerID, iMsgID, ref structMessage, iObjectID, headserverID); } public uint GetWorldServerID() { return m_worldServerID; } public int GetBattleServerCount() { return m_battleSvrNum; } } }