BITKit/Src/Unity/Scripts/NetProvider/Kcp/MonoKcpClient.cs

281 lines
7.0 KiB
C#
Raw Normal View History

2023-08-23 01:59:26 +08:00
using System;
using System.Threading;
using System.Threading.Tasks;
2024-06-08 10:07:40 +08:00
using BITKit.Net.Examples;
2023-08-23 01:59:26 +08:00
using UnityEngine;
using Cysharp.Threading.Tasks;
namespace BITKit.Net.Kcp
{
2024-06-26 17:53:10 +08:00
[CustomType(typeof(INetClient))]
[CustomType(typeof(INetProvider))]
2023-08-23 01:59:26 +08:00
public class MonoKcpClient : MonoBehaviour,INetClient,INetProvider
{
internal static MonoKcpClient Singleton { get; private set; }
2024-03-31 23:31:00 +08:00
[SerializeField,ReadOnly] private int rate;
[SerializeReference,SubclassSelector] private ITicker ticker;
2023-08-23 01:59:26 +08:00
[SerializeField] private string m_host;
[SerializeField] private ushort m_port;
[SerializeField] private bool connectOnStart;
[SerializeField] private bool autoReconnect;
2024-06-20 17:28:56 +08:00
2024-06-17 16:29:39 +08:00
[Header(Constant.Header.Debug)]
2024-06-17 14:38:09 +08:00
[SerializeField]
2024-06-20 17:28:56 +08:00
[ReadOnly] private int id;
[SerializeField]
2024-06-17 14:38:09 +08:00
[ReadOnly]private Vector2 traffic;
[SerializeField]
[ReadOnly]private string upTraffic;
[SerializeField]
[ReadOnly]private string downTraffic;
2024-06-17 16:29:39 +08:00
[SerializeField, ReadOnly] private bool isConnected;
2024-06-17 14:38:09 +08:00
2023-08-23 01:59:26 +08:00
#if UNITY_EDITOR
[SerializeField] private Optional<string> allowDebugHost;
[SerializeField] private Optional<ushort> allowDebugPort;
#endif
2024-03-31 23:31:00 +08:00
private readonly DeltaTimer timer = new();
2023-08-23 01:59:26 +08:00
private KcpNetClient client;
private INetClient _netClientImplementation=>client;
private INetProvider _netProviderImplementation=>client;
2024-06-17 16:29:39 +08:00
2024-06-20 17:28:56 +08:00
private readonly IntervalUpdate _reconnectInterval = new(3);
2023-08-23 01:59:26 +08:00
public event Action OnStartConnect
{
add => _netClientImplementation.OnStartConnect += value;
remove => _netClientImplementation.OnStartConnect -= value;
}
public event Action OnConnected
{
add => _netClientImplementation.OnConnected += value;
remove => _netClientImplementation.OnConnected -= value;
}
public event Action OnDisconnected
{
add => _netClientImplementation.OnDisconnected += value;
remove => _netClientImplementation.OnDisconnected -= value;
}
public event Action OnConnectedFailed
{
add => _netClientImplementation.OnConnectedFailed += value;
remove => _netClientImplementation.OnConnectedFailed -= value;
}
public bool IsConnected => _netClientImplementation.IsConnected;
2024-03-31 23:31:00 +08:00
public bool ManualTick
{
get => client.ManualTick;
set => client.ManualTick = value;
}
2023-08-23 01:59:26 +08:00
public int Ping => _netClientImplementation.Ping;
public int Id => _netClientImplementation.Id;
public void Disconnect()
{
_netClientImplementation.Disconnect();
}
public UniTask<bool> Connect(string address = "localhost", ushort port = 27014)
{
2024-03-31 23:31:00 +08:00
if(address is "localhost" or null)
address = m_host;
if(port is 27014 or 0)
port = m_port;
2024-06-27 18:53:49 +08:00
m_host = address;
m_port = port;
2023-08-23 01:59:26 +08:00
return _netClientImplementation.Connect(address, port);
}
public void SendServerMessage(string message)
{
_netClientImplementation.SendServerMessage(message);
}
public void ServerCommand<T>(T command = default)
{
_netProviderImplementation.ServerCommand(command);
}
public void AllClientCommand<T>(T command = default)
{
_netProviderImplementation.AllClientCommand(command);
}
public void ClientCommand<T>(int id, T command)
{
_netProviderImplementation.ClientCommand(id, command);
}
2024-06-12 16:49:42 +08:00
public UniTask<T> GetFromServer<T>(string path = null, params object[] pars)
{
return client.GetFromServer<T>(path, pars);
}
public UniTask<T> GetFromClient<T>(int id, string path = null, params object[] pars)
{
return client.GetFromClient<T>(id, path, pars);
}
2024-06-12 16:01:56 +08:00
public UniTask<T> GetFromServer<T>(string path=null,T command = default)
2023-08-23 01:59:26 +08:00
{
2024-06-12 16:01:56 +08:00
return _netProviderImplementation.GetFromServer<T>(path,command);
2023-08-23 01:59:26 +08:00
}
2024-06-12 16:01:56 +08:00
public UniTask<T> GetFromClient<T>(int id,string path=null, T command = default)
2023-08-23 01:59:26 +08:00
{
2024-06-12 16:01:56 +08:00
return _netProviderImplementation.GetFromClient<T>(id,path, command);
2023-08-23 01:59:26 +08:00
}
public void AddRpcHandle(object rpcHandle)
{
_netProviderImplementation.AddRpcHandle(rpcHandle);
}
public void AddCommandListener<T>(Action<T> handle)
{
_netProviderImplementation.AddCommandListener(handle);
}
2024-06-08 15:12:48 +08:00
public void RemoveCommandListener<T>(Action<T> handle)
2023-08-23 01:59:26 +08:00
{
2024-06-08 15:12:48 +08:00
_netProviderImplementation.RemoveCommandListener(handle);
2023-08-23 01:59:26 +08:00
}
2024-06-08 15:12:48 +08:00
public void AddCommandListener<T>(Func<T, UniTask<T>> func)
2024-06-08 10:07:40 +08:00
{
2024-06-08 15:12:48 +08:00
_netProviderImplementation.AddCommandListener(func);
}
public void RemoveCommandListener<T>(Func<T, UniTask<T>> func)
{
_netProviderImplementation.RemoveCommandListener(func);
2024-06-08 10:07:40 +08:00
}
2023-08-23 01:59:26 +08:00
public void SendRT(string rpcName, params object[] pars)
{
_netProviderImplementation.SendRT(rpcName, pars);
}
public void SendTargetRT(int id, string rpcName, params object[] pars)
{
_netProviderImplementation.SendTargetRT(id, rpcName, pars);
}
public void SendAllRT(string rpcName, params object[] pars)
{
_netProviderImplementation.SendAllRT(rpcName, pars);
}
public void Tick()
{
_netProviderImplementation.Tick();
2024-06-17 14:38:09 +08:00
2023-08-23 01:59:26 +08:00
}
public void HandShake()
{
_netProviderImplementation.HandShake();
}
2024-03-31 23:31:00 +08:00
private void Awake()
{
Singleton = this;
client = new KcpNetClient();
}
2023-08-23 01:59:26 +08:00
private void Start()
{
2024-03-31 23:31:00 +08:00
if (ticker is not null)
{
ManualTick = true;
ticker.Add(OnTick);
}
destroyCancellationToken.Register(() =>
{
if (IsConnected)
Disconnect();
ticker?.Remove(OnTick);
});
if (!connectOnStart) return;
2023-08-23 01:59:26 +08:00
#if UNITY_EDITOR
var _host = allowDebugHost.Allow ? allowDebugHost.Value : m_host;
var _port = allowDebugPort.Allow ? allowDebugPort.Value : m_port;
Connect(_host, _port).Forget();
#else
Connect(m_host, m_port).Forget();
#endif
}
2024-03-31 23:31:00 +08:00
private void OnTick(float obj)
2023-08-23 01:59:26 +08:00
{
2024-06-20 10:04:18 +08:00
if (destroyCancellationToken.IsCancellationRequested) return;
2024-06-17 16:29:39 +08:00
if (client.IsConnected is false && autoReconnect)
{
if (_reconnectInterval.AllowUpdate)
2024-06-20 17:28:56 +08:00
{
if (client.IsConnecting is false)
{
client.Connect(m_host, m_port).Forget();
}
}
2024-06-17 16:29:39 +08:00
}
2024-06-20 17:28:56 +08:00
id = Id;
2024-03-31 23:31:00 +08:00
timer.Update(obj);
rate = timer;
Tick();
2024-06-17 14:38:09 +08:00
traffic = client.Traffic;
upTraffic = NetUtils.GetFileSize((long)traffic.x);
downTraffic = NetUtils.GetFileSize((long)traffic.y);
2024-06-17 16:29:39 +08:00
isConnected = IsConnected;
2024-03-31 23:31:00 +08:00
}
[BIT]
private void EditorConnect()
{
BITAppForUnity.ThrowIfNotPlaying();
Connect(m_host, m_port).Forget();
}
[BIT]
private void EditorDisconnect()
{
BITAppForUnity.ThrowIfNotPlaying();
Disconnect();
2023-08-23 01:59:26 +08:00
}
2024-06-08 10:07:40 +08:00
[BIT]
private async void Hello()
{
BITAppForUnity.ThrowIfNotPlaying();
2024-06-12 16:01:56 +08:00
var value =await GetFromServer<SimplePing>(null,new SimplePing()
2024-06-08 10:07:40 +08:00
{
StartTime = DateTime.Now
});
BIT4Log.Log<MonoKcpClient>($"已返回\n开始:{value.StartTime}\n结束:{value.EndTime}\n延迟:{(value.EndTime-value.StartTime).TotalMilliseconds}ms");
2024-06-14 17:50:29 +08:00
2024-06-12 16:49:42 +08:00
var hello =
await GetFromServer<string>(
nameof(KCPNetServer.MyRpcTest),
"hello"
);
2024-06-14 17:50:29 +08:00
BIT4Log.Log<MonoKcpClient>($"延迟:{(DateTime.Now-value.StartTime).TotalMilliseconds}ms");
2024-06-12 16:49:42 +08:00
BIT4Log.Log<MonoKcpClient>($"已返回\n{hello}");
var helloAsync =
await GetFromServer<string>(
nameof(KCPNetServer.MyRpcTestAsync),
"hello"
);
BIT4Log.Log<MonoKcpClient>($"已返回\n{helloAsync}");
2024-06-08 10:07:40 +08:00
}
2023-08-23 01:59:26 +08:00
}
}