public void OnConnected(object sender, EventArgs e)
{
switch (serverType)
{
case ServerType.BalanceServer:
{
CGLCtrl_GameLogic.Instance.BsOneClinetLogin();
}
break;
case ServerType.GateServer:
{
++m_n32ConnectTimes;
if (m_n32ConnectTimes > 1)
{
CGLCtrl_GameLogic.Instance.EmsgTocsAskReconnect();
}
else
{
CGLCtrl_GameLogic.Instance.GameLogin();
}
EventCenter.Broadcast(EGameEvent.eGameEvent_ConnectServerSuccess);
}
break;
case ServerType.LoginServer:
{
CGLCtrl_GameLogic.Instance.EmsgToLs_AskLogin();
}
break;
}
}
public void Connect()
{
if (!canReconnect) return;
if (m_CanConnectTime > Time.time) return;
if (m_Client != null)
throw new Exception("fuck, The socket is connecting, cannot connect again!");
if (m_Connecting != null)
throw new Exception("fuck, The socket is connecting, cannot connect again!");
Debugger.Log("IClientSession Connect");
IPAddress ipAddress = IPAddress.Parse(m_IP);
try
{
m_Connecting = new TcpClient();
mConnectResult = m_Connecting.BeginConnect(m_IP, m_Port, null, null);
m_ConnectOverCount = 0;
m_ConnectOverTime = Time.time + 2;
}
catch (Exception exc)
{
Debugger.LogError(exc.ToString());
m_Client = m_Connecting;
m_Connecting = null;
mConnectResult = null;
OnConnectError(m_Client, null);
}
}
public void Update(float fDeltaTime)
{
if (m_Client != null)
{
DealWithMsg(); //这行很重要,接收完的消息要循环调用处理
if (mRecvResult != null)
{
if (m_RecvOverCount > 200 && Time.time > m_RecvOverTime)
{
Debugger.LogError("recv data over 200, so close network.");
Close();
return;
}
++m_RecvOverCount;
if (mRecvResult.IsCompleted)
{
try
{
Int32 n32BytesRead = m_Client.GetStream().EndRead(mRecvResult);
m_RecvPos += n32BytesRead;
if (n32BytesRead == 0)
{
Debugger.LogError("can't recv data now, so close network 2.");
Close();
return;
}
}
catch (Exception exc)
{
Debugger.LogError(exc.ToString());
Close();
return;
}
OnDataReceived(null, null); //这一行很重要,数据接收处理
if (m_Client != null)
{
try
{
mRecvResult = m_Client.GetStream().BeginRead(m_RecvBuffer, m_RecvPos, m_RecvBuffer.Length - m_RecvPos, null, null);
m_RecvOverTime = Time.time + mRecvOverDelayTime;
m_RecvOverCount = 0;
}
catch (Exception exc)
{
Debugger.LogError(exc.ToString());
Close();
return;
}
}
}
}
if (m_Client != null && m_Client.Connected == false)
{
Debugger.LogError("client is close by system, so close it now.");
Close();
return;
}
}
else if (m_Connecting != null)
{
if (m_ConnectOverCount > 200 && Time.time > m_ConnectOverTime)
{
Debugger.LogError("can't connect, so close network.");
m_Client = m_Connecting;
m_Connecting = null;
mConnectResult = null;
OnConnectError(m_Client, null);
return;
}
++m_ConnectOverCount;
if (mConnectResult.IsCompleted)
{
m_Client = m_Connecting;
m_Connecting = null;
mConnectResult = null;
if (m_Client.Connected)
{
try
{
m_Client.NoDelay = true;
m_Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 2000);
m_Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
m_Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
mRecvResult = m_Client.GetStream().BeginRead(m_RecvBuffer, 0, m_RecvBuffer.Length, null, null);
m_RecvOverTime = Time.time + mRecvOverDelayTime;
m_RecvOverCount = 0;
OnConnected(m_Client, null);
}
catch (Exception exc)
{
Debugger.LogError(exc.ToString());
Close();
return;
}
}
else
{
OnConnectError(m_Client, null);
}
}
}
else
{
Connect();
}
}
public void OnDataReceived(object sender, DataEventArgs e) //对Buffer进行分段解析
{
int m_CurPos = 0;
while (m_RecvPos - m_CurPos >= 8)
{
int len = BitConverter.ToInt32(m_RecvBuffer, m_CurPos);
int type = BitConverter.ToInt32(m_RecvBuffer, m_CurPos + 4); //取出消息类型
if (len > m_RecvBuffer.Length)
{
Debugger.LogError("can't pause message" + "type=" + type + "len=" + len);
break;
}
if (len > m_RecvPos - m_CurPos)
{
break;//wait net recv more buffer to parse.
}
//获取stream
System.IO.MemoryStream tempStream = null;
if (mReceiveStreamsPool.Count>0)
{
tempStream = mReceiveStreamsPool[0];
tempStream.SetLength(0);
tempStream.Position = 0;
mReceiveStreamsPool.RemoveAt(0);
}
else
{
tempStream = new System.IO.MemoryStream();
}
//往stream填充网络数据
tempStream.Write(m_RecvBuffer, m_CurPos + 8, len - 8);
tempStream.Position = 0;
m_CurPos += len;
//下面这两行很重要,对Buffer进行进一步的分解保存
mReceiveMsgIDs.Add(type);
mReceiveStreams.Add(tempStream);
}
if (m_CurPos > 0)
{
m_RecvPos = m_RecvPos - m_CurPos;
if (m_RecvPos < 0)
{
Debug.LogError("m_RecvPos < 0");
}
if (m_RecvPos > 0)
{
Buffer.BlockCopy(m_RecvBuffer, m_CurPos, m_RecvBuffer, 0, m_RecvPos);
}
}
}
public void DealWithMsg()
{
while (mReceiveMsgIDs.Count>0 && mReceiveStreams.Count>0)
{
int type = mReceiveMsgIDs[0];
System.IO.MemoryStream iostream = mReceiveStreams[0];
mReceiveMsgIDs.RemoveAt(0);
mReceiveStreams.RemoveAt(0);
#if UNITY_EDITOR
#else
try
{
#endif
#if LOG_FILE && UNITY_EDITOR
if (type != 1)
{
string msgName = "";
if (Enum.IsDefined(typeof(BSToGC.MsgID), type))
{
msgName = ((BSToGC.MsgID)type).ToString();
}
else if (Enum.IsDefined(typeof(LSToGC.MsgID), type))
{
msgName = ((LSToGC.MsgID)type).ToString();
}
else if (Enum.IsDefined(typeof(GSToGC.MsgID), type))
{
msgName = ((GSToGC.MsgID)type).ToString();
}
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(@"E:\Log.txt", true))
{
sw.WriteLine(Time.time + " 收到消息:\t" + type + "\t" + msgName);
}
}
#endif
CGLCtrl_GameLogic.Instance.HandleNetMsg(iostream, type); //这行很重要,分发处理交给另一个单例去做
if (mReceiveStreamsPool.Count<100)
{
mReceiveStreamsPool.Add(iostream);
}
else
{
iostream = null;
}
#if UNITY_EDITOR
#else
}
catch (Exception ecp)
{
Debugger.LogError("Handle Error msgid: " + type);
}
#endif
}
}
public partial class CGLCtrl_GameLogic : UnitySingleton<CGLCtrl_GameLogic>
{
const int PROTO_DESERIALIZE_ERROR = -1;
public void HandleNetMsg(System.IO.Stream stream, int n32ProtocalID)
{
//Debug.Log("n32ProtocalID " + (GSToGC.MsgID)n32ProtocalID);
switch (n32ProtocalID)
{
case (Int32)GSToGC.MsgID.eMsgToGCFromGS_GCAskPingRet:
OnNetMsg_NotifyPing(stream);
break;
case (Int32)GSToGC.MsgID.eMsgToGCFromGS_NotifyUserBaseInfo:
OnNetMsg_NotifyUserBaseInfo(stream);
break;
case (Int32)GSToGC.MsgID.eMsgToGCFromGS_GCAskRet:
OnNetMsg_NotifyReturn(stream);
break;
case (Int32)GSToGC.MsgID.eMsgToGCFromGS_NotifyNetClash:
OnNetMsg_NotifyNetClash(stream);
break;
case (Int32)GSToGC.MsgID.eMsgToGCFromGS_NotifyBattleBaseInfo:
OnNetMsg_NotifyBattleBaseInfo(stream);
break;
case (Int32)GSToGC.MsgID.eMsgToGCFromGS_NotifyBattleSeatPosInfo:
OnNetMsg_NotifyBattleSeatPosInfo(stream);
break;
Int32 OnNetMsg_NotifyServerAddr(Stream stream)
{
LoginCtrl.Instance.UpdateServerAddr(stream);
return (Int32)EErrorCode.eNormal;
}
FR:海涛高软(hunk Xu)