// ***********************************************************************
// 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
}
}