2025-05-18 01:04:31 +08:00

465 lines
9.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ***********************************************************************
// Assembly : Unity
// Author : Kimch
// Created : 2019-5-16
//
// Last Modified By : Kimch
// Last Modified On :
// ***********************************************************************
// <copyright file= "NetworkProxy" company=""></copyright>
// <summary></summary>
// ***********************************************************************
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
/// <summary>
///
/// </summary>
private IConnector _connector;
/// <summary>
///
/// </summary>
private GameNetworkAdapter _adapter;
/// <summary>
///
/// </summary>
private readonly Queue<GamePacket> _sendQueue = new Queue<GamePacket>();
/// <summary>
///
/// </summary>
private bool _connecting;
/// <summary>
/// 最大重连次数
/// </summary>
private int _maxReconnection = 3;
/// <summary>
/// 当前重连次数
/// </summary>
private int _curReconnection = -1;
/// <summary>
/// 重连时间
/// </summary>
private float _reconnectionTimer = 0f;
/// <summary>
/// 重连间隔
/// </summary>
private float _reconnectionInterval = 2f;
/// <summary>
/// 是否连接
/// </summary>
public bool connected
{
get;
private set;
}
/// <summary>
///
/// </summary>
public string connectURL
{
get;
set;
}
public void AutoConnect()
{
if (_curReconnection == -1)
{
_curReconnection = 0;
Connect();
}
}
/// <summary>
/// 不要用对内
/// </summary>
public void Connect()
{
if (!string.IsNullOrEmpty(connectURL))
{
Connect(connectURL);
}
}
/// <summary>
/// 不要用对内
/// </summary>
/// <param name="address">"127.0.0.1:12356"</param>
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);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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($"网络包格式错误");
}
}
/// <summary>
/// 收到网络错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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, () =>
// {
// });
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnNetworkClosed(object sender, NetworkClosedEventArgs e)
{
_connecting = false;
connected = false;
UnityEngine.Debug.Log("OnNetworkClosed.");
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
/// <summary>
/// 上一次发送过去的时间
/// </summary>
public float pingElapseSeconds { get; set; }
/// <summary>
/// 丢失Ping包
/// </summary>
public int lossPingCount { get; set; }
private float _pingInterval = DEFAULT_PING_INTERVAL;
/// <summary>
/// 获取或设置Ping间隔时长以秒为单位。
/// </summary>
public float pingInterval
{
get { return _pingInterval; }
set { _pingInterval = value; }
}
/// <summary>
/// 发包延迟(单位秒)
/// </summary>
public float lastPing { get; set; }
/// <summary>
/// 平均延迟(单位秒)
/// </summary>
public float averagePing { get; set; }
/// <summary>
///
/// </summary>
/// <param name="resetPingElapseSeconds"></param>
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, // 没有足够货币
}
/// <summary>
///
/// </summary>
/// <param name="error"></param>
public void ProcessErrorCode(ErrorCode error)
{
ProcessError((int)error);
}
/// <summary>
///
/// </summary>
/// <param name="error"></param>
public void ProcessError(int error)
{
//var errorItem = ItemProxy.Instance.GetStaticItem<ItemError>(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; } }
/// <summary>
///
/// </summary>
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<int> 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
}
}