// *********************************************************************** // Assembly : Unity // Author : Kimch // Created : 2019-5-16 // // Last Modified By : Kimch // Last Modified On : // *********************************************************************** // // // *********************************************************************** namespace G { using System; using System.Collections.Generic; using F; using F.Network; using PureMVC.Interfaces; using UnityEngine; public sealed class NetworkProxy : GameProxy { #region Connector /// /// /// private IConnector _connector; /// /// /// private GameNetworkAdapter _adapter; /// /// /// private readonly Queue _sendQueue = new Queue(); /// /// /// private bool _connecting; /// /// 最大重连次数 /// private int _maxReconnection = 3; /// /// 当前重连次数 /// private int _curReconnection = -1; /// /// 重连时间 /// private float _reconnectionTimer = 0f; /// /// 重连间隔 /// private float _reconnectionInterval = 2f; /// /// 是否连接 /// public bool connected { get; private set; } /// /// /// public string connectURL { get; set; } public void AutoConnect() { if (_curReconnection == -1) { _curReconnection = 0; Connect(); } } /// /// 不要用对内 /// public void Connect() { if (!string.IsNullOrEmpty(connectURL)) { Connect(connectURL); } } /// /// 不要用对内 /// /// "127.0.0.1:12356" public void Connect(string address) { if (!connected) { _connecting = true; _connector.Connect(address); } } public void Send(GamePacket packet) { if (connected) { _connector.Send(packet); } else { AutoConnect(); _sendQueue.Enqueue(packet); } } /// /// /// /// /// private void OnNetworkRecv(object sender, IPacket e) { if (e is GamePacket packet) { if (packet.error == GamePacket.ERROR_CODE_OK) { if (packet.id == 0) { ProcessPing(packet); } else { #if UNITY_EDITOR Debug.Log("S2C-----id:" + e.id + "------" + e.data.ToString()); #endif KFramework.GameFacade.Recv(packet); } } else { Debug.Log($"NetWork Error : {packet.error}"); ProcessError(packet.error); } } else { Debug.Log($"网络包格式错误"); } } /// /// 收到网络错误 /// /// /// private void OnNetworkError(object sender, NetworkErrorEventArgs e) { switch (e.errorCode) { case NetworkError.ConnectError: case NetworkError.SendError: case NetworkError.ReceiveError: case NetworkError.SocketError: case NetworkError.AddressError: _connecting = false; connected = false; break; case NetworkError.SerializeError: case NetworkError.DeserializePacketHeaderError: case NetworkError.DeserializePacketError: _connecting = false; connected = false; _connector.Close(); break; case NetworkError.CustomError: break; } var errorMessage = $"{e.errorCode} {e.errorMessage} {e.customErrorData}"; Debug.Log(errorMessage); //UI.MessageBox.ShowMessage("网络错误", errorMessage, () => // { // }); } /// /// /// /// /// private void OnNetworkClosed(object sender, NetworkClosedEventArgs e) { _connecting = false; connected = false; UnityEngine.Debug.Log("OnNetworkClosed."); } /// /// /// /// /// private void OnNetworkConnected(object sender, NetworkConnectedEventArgs e) { _connecting = false; connected = true; UnityEngine.Debug.Log("NetworkConnected."); } #endregion #region Ping private const float DEFAULT_PING_INTERVAL = 30f; private DateTime _sendPingTime = DateTime.MinValue; /// /// 上一次发送过去的时间 /// public float pingElapseSeconds { get; set; } /// /// 丢失Ping包 /// public int lossPingCount { get; set; } private float _pingInterval = DEFAULT_PING_INTERVAL; /// /// 获取或设置Ping间隔时长,以秒为单位。 /// public float pingInterval { get { return _pingInterval; } set { _pingInterval = value; } } /// /// 发包延迟(单位秒) /// public float lastPing { get; set; } /// /// 平均延迟(单位秒) /// public float averagePing { get; set; } /// /// /// /// public void Reset(bool resetPingElapseSeconds) { if (resetPingElapseSeconds) { pingElapseSeconds = 0f; } lossPingCount = 0; } public void SetLastSend() { _sendPingTime = DateTime.UtcNow; } public void SetLastRecv() { if (_sendPingTime != DateTime.MinValue) { lastPing = (float)((DateTime.UtcNow - _sendPingTime).TotalSeconds); _sendPingTime = DateTime.MinValue; averagePing = (averagePing + lastPing) * 0.5f; } } public bool SendPing() { Debug.Log("SendPing"); Send(new GamePacket { //id = msg.C2SHeartBeat.MessageType, //data = new msg.C2SHeartBeat() }); SetLastSend(); return true; } public void ProcessPing(GamePacket packet) { Debug.Log("RecvPing"); SetLastRecv(); this.lossPingCount--; } private void UpdatePing(float deltaTime) { if (pingInterval > 0f) { var needSendPing = false; int pingLossCount = 0; pingElapseSeconds += deltaTime; if (pingElapseSeconds >= pingInterval) { needSendPing = true; this.lossPingCount++; } if (needSendPing && SendPing()) { pingElapseSeconds = 0f; if (pingLossCount > 0) { } } } } #endregion #region Error public enum ErrorCode { PLAYER_NOT_ENOUGH_COIN = 1000, // 金币不够 PLAYER_NOT_ENOUGH_STONE = 1001, // 钻石不够 PLAYER_NOT_ENOUGH_YUANSHEN = 1002, // 钻石不够 PLAYER_NOT_ENOUGH_CURRENCY = 1003, // 没有足够货币 } /// /// /// /// public void ProcessErrorCode(ErrorCode error) { ProcessError((int)error); } /// /// /// /// public void ProcessError(int error) { //var errorItem = ItemProxy.Instance.GetStaticItem(error); //if (errorItem != null) //{ // switch (errorItem.type) // { // case 0: // break; // case 1: // break; // case 2: // break; // case 3: // break; // case 4: // break; // default: // break; // } //} //else //{ //} } #endregion #region Proxy private static NetworkProxy _Instance; public static NetworkProxy Instance { get { return _Instance; } } /// /// /// public override void Init() { KFramework.NetworkManager.networkConnected += this.OnNetworkConnected; KFramework.NetworkManager.networkClosed += this.OnNetworkClosed; KFramework.NetworkManager.networkError += this.OnNetworkError; //_adapter = new GameNetworkAdapter(); //_connector = KFramework.NetworkManager.CreateConnector("GameConnector", _adapter); //_connector.SetDefaultHandler(OnNetworkRecv); } static readonly int[] _ListNotificationInterests = new int[] { GlobalDefine.EVENT_NETWORK_PACKET, }; public override IList ListNotificationInterests() { return _ListNotificationInterests; } public override void HandleNotification(INotification notification) { OnNetworkRecv(notification.Type, notification.Body as IPacket); } private void Awake() { _Instance = this; } private void OnDestroy() { if (_connector != null) { _connector.Close(); } } private void LateUpdate() { return; if (connected) { while (connected && _sendQueue.Count > 0) { _curReconnection = 0; Send(_sendQueue.Dequeue()); } UpdatePing(Time.deltaTime); } else if (!_connecting) { if (_curReconnection >= 0) { _reconnectionTimer += Time.deltaTime; if (_reconnectionTimer > _reconnectionInterval && _curReconnection < _maxReconnection) { Connect(); _curReconnection++; _reconnectionTimer = 0; if (_curReconnection >= _maxReconnection) { //UI.MessageBox.ShowMessage("网络连接断开", "请重新连接", () => // { // _curReconnection = 0; // }); } Debug.Log("自动重连 " + _curReconnection); } } } } #endregion } }