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.
 
 
 
 
 
 

493 lines
20 KiB

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using ProtoCSStruct;
namespace Sog
{
/// <summary>
/// 消息发送器,结构体版本
/// </summary>
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()
{
}
/// <summary>
/// 初始化,支持线程安全可选项,默认不支持多线程
/// </summary>
/// <param name="serverID"></param>
/// <param name="cluster"></param>
/// <param name="clusterInstId"></param>
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<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_nameServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
public void SendToVersionServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_versionServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
public void SendToFriendServer<T>(StructPacket packet, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
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<T>(), iObjectID, headserverID);
}
public void SendToFriendServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
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<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_worldServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
public void SendToOperationServer<T>(StructPacket packet, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_OperationServerID, packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
}
public void SendToPlayerOpServer<T>(StructPacket packet, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_PlayerOpServerID, packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
}
public void SendToPlayerOpServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_PlayerOpServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
/// <summary>
/// cluster层向多个World发消息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="iMsgID"></param>
/// <param name="structMessage"></param>
/// <param name="iObjectID"></param>
/// <param name="WorldIds"></param>
/// <param name="headserverID"></param>
public void SendToWorldServerBymWorldIds<T>(int iMsgID, ref T structMessage, long iObjectID, int[] WorldIds, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
foreach (var WorldId in WorldIds)
{
var worldServerID = ServerIDUtils.MakeServerID(WorldId, (int)ServerType.World, 1);
SendToServerByID(worldServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
}
public void SendToMailServerBymWorldIds<T>(int iMsgID, ref T structMessage, long iObjectID, int[] WorldIds, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
foreach (var WorldId in WorldIds)
{
var mailServerID = ServerIDUtils.MakeServerID(WorldId, (int)ServerType.Mail, 1);
SendToServerByID(mailServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
}
public void SendToWorldServer<T>(StructPacket packet, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_worldServerID, packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
}
public void SendToRankServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_rankServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
public void SendToRankServer<T>(StructPacket packet, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_rankServerID, packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
}
public void SendToChatServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_chatServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
#region 以下方法都是要废弃的,battleServerID 和 gameServerID 都不唯一了,全部废弃 全部废弃 全部废弃
//battle修改下,一定要playerSession
//public void SendToBattleServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
// where T : struct, IStructMessage<T>
//{
// 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<T>(StructPacket packet, long iObjectID, uint headserverID = 0)
// where T : struct, IStructMessage<T>
//{
// 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<T>(), iObjectID, headserverID);
// //SendToServerByID(TransBattleIDToBattleServerID(battleID), packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
//}
#endregion
public void SendToMailServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_mailServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
/// <summary>
/// 转发消息,注意,这个StructPacket请尽量不要自己new!!!
/// </summary>
/// <param name="dstserverID"></param>
/// <param name="packet"></param>
public void SendToServerByID<T>(uint dstserverID, StructPacket packet)
where T : struct, IStructMessage<T>
{
SendToServerByID(dstserverID, packet.MsgID, ref packet.GetMessage<T>(), packet.ObjectID, packet.ServerID);
}
public void SendToServerByID<T>(uint dstserverID, StructPacket packet, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(dstserverID, packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
}
private MessageData PackMessagePrintf<T>(uint dstserverID, int iMsgID, ref T structMessage, long iObjectID, uint headserverID)
where T : struct, IStructMessage<T>
{
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<T>(uint dstserverID, int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
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<T>(int serverType, int iMsgID, ref T structMessage, long iObjectID, uint headserverID)
where T : struct, IStructMessage<T>
{
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<T>(int serverType, StructPacket packet)
where T : struct, IStructMessage<T>
{
uint serverID = (uint)(serverType << 8);
MessageData message = PackMessagePrintf(serverID, packet.MsgID, ref packet.GetMessage<T>(), packet.ObjectID, packet.ServerID);
if (message.Buffer.Data == null)
{
return;
}
m_cluster.Broadcast(serverType, message);
}
public void SendToHttpProxyWorldServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_httpProxyWorldServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
public void SendToHttpProxyPayServer<T>(StructPacket packet)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_httpProxyPayServerID, packet.MsgID, ref packet.GetMessage<T>(), packet.ObjectID);
}
public void SendToRealmlistServer<T>(StructPacket packet, long iObjectID, uint headserverID)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_realmlistServerID, packet.MsgID, ref packet.GetMessage<T>(), iObjectID, headserverID);
}
public void SendToRealmlistServer<T>(int iMsgID, ref T structMessage, long iObjectID, uint headserverID = 0)
where T : struct, IStructMessage<T>
{
SendToServerByID(m_realmlistServerID, iMsgID, ref structMessage, iObjectID, headserverID);
}
public uint GetWorldServerID()
{
return m_worldServerID;
}
public int GetBattleServerCount()
{
return m_battleSvrNum;
}
}
}