1
This commit is contained in:
@@ -14,6 +14,7 @@ using System.Numerics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using BITKit.Net.Examples;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Unity.Mathematics;
|
||||
|
||||
@@ -21,6 +22,26 @@ namespace BITKit.Net
|
||||
{
|
||||
public class KcpNetClient:INetClient,INetProvider
|
||||
{
|
||||
private readonly ILogger<KcpNetClient> _logger;
|
||||
public KcpNetClient(ILogger<KcpNetClient> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_client = new KcpClient(
|
||||
OnConnectedInternal,
|
||||
OnData,
|
||||
OnDisconnectInternal,
|
||||
OnError,
|
||||
KCPNet.Config
|
||||
);
|
||||
_timer.Elapsed += Tick;
|
||||
_logger.LogInformation("已创建KCP客户端");
|
||||
AddCommandListener<NetClientAllocateIdCommand>(x =>
|
||||
{
|
||||
Id = x.Id;
|
||||
});
|
||||
_isConnected.AddListener(ConnectionCallback);
|
||||
}
|
||||
|
||||
public event Action OnStartConnect;
|
||||
public event Action OnConnected;
|
||||
public event Action OnDisconnected;
|
||||
@@ -29,14 +50,14 @@ namespace BITKit.Net
|
||||
public bool IsConnecting { get; private set; }
|
||||
public double RpcTimeOut { get; set; } = 5;
|
||||
public bool AutoReconnect { get; set; } = true;
|
||||
public float2 Traffic { get; set; }
|
||||
public float2 Traffic { get; private set; }
|
||||
public bool ManualTick { get; set; }
|
||||
|
||||
private readonly IntervalUpdate _reconnectInterval = new(1);
|
||||
|
||||
public int Ping { get; private set; }
|
||||
public int Id { get; private set; } = -1;
|
||||
private readonly KcpClient client;
|
||||
private readonly KcpClient _client;
|
||||
|
||||
private readonly ConcurrentQueue<byte[]> _commandQueue = new();
|
||||
|
||||
@@ -50,7 +71,7 @@ namespace BITKit.Net
|
||||
private readonly GenericEvent _events = new();
|
||||
|
||||
private readonly ValidHandle _isConnected = new();
|
||||
|
||||
private bool _userConnected;
|
||||
private int _index = int.MinValue;
|
||||
private readonly ConcurrentDictionary<int, object> _p2p = new();
|
||||
private readonly ConcurrentDictionary<string,Func<object,UniTask<object>>> _rpc = new();
|
||||
@@ -64,23 +85,7 @@ namespace BITKit.Net
|
||||
private ushort _connectedPort = 27014;
|
||||
|
||||
private readonly byte[] _heartBeat = new byte[] { (byte)NetCommandType.Heartbeat };
|
||||
public KcpNetClient()
|
||||
{
|
||||
client = new KcpClient(
|
||||
OnConnectedInternal,
|
||||
OnData,
|
||||
OnDisconnectInternal,
|
||||
OnError,
|
||||
KCPNet.Config
|
||||
);
|
||||
_timer.Elapsed += Tick;
|
||||
BIT4Log.Log<KcpNetClient>("已创建KCP客户端");
|
||||
AddCommandListener<NetClientAllocateIdCommand>(x =>
|
||||
{
|
||||
Id = x.Id;
|
||||
});
|
||||
_isConnected.AddListener(ConnectionCallback);
|
||||
}
|
||||
|
||||
|
||||
private async void ConnectionCallback(bool x)
|
||||
{
|
||||
@@ -88,12 +93,12 @@ namespace BITKit.Net
|
||||
if (x)
|
||||
{
|
||||
OnConnected?.Invoke();
|
||||
BIT4Log.Log<KcpNetClient>("连接成功");
|
||||
_logger.LogInformation("连接成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
OnDisconnected?.Invoke();
|
||||
BIT4Log.Log<KcpNetClient>("连接已断开");
|
||||
_logger.LogInformation("连接已断开");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +109,14 @@ namespace BITKit.Net
|
||||
}
|
||||
|
||||
public async void Disconnect()
|
||||
{
|
||||
_userConnected = false;
|
||||
DisconnectInternal();
|
||||
}
|
||||
private async void DisconnectInternal()
|
||||
{
|
||||
IsConnecting = false;
|
||||
client.Disconnect();
|
||||
_client.Disconnect();
|
||||
_isConnected.RemoveElement(this);
|
||||
_timer.Stop();
|
||||
try
|
||||
@@ -117,6 +127,7 @@ namespace BITKit.Net
|
||||
catch (OperationCanceledException){}
|
||||
}
|
||||
|
||||
private string _lastHostName;
|
||||
public async UniTask<bool> Connect(string address = "127.0.0.1", ushort port = 27014)
|
||||
{
|
||||
if (IsConnecting)
|
||||
@@ -124,7 +135,7 @@ namespace BITKit.Net
|
||||
BIT4Log.Warning<KcpNetClient>("正在连接中");
|
||||
return false;
|
||||
}
|
||||
|
||||
_userConnected = true;
|
||||
//如果address是域名,解析为Ip
|
||||
if (address.Contains("."))
|
||||
{
|
||||
@@ -132,7 +143,11 @@ namespace BITKit.Net
|
||||
if (ip.Length > 0)
|
||||
{
|
||||
address = ip[0].ToString();
|
||||
BIT4Log.Log<KcpNetClient>($"解析域名:{address}");
|
||||
if (_lastHostName != address)
|
||||
{
|
||||
_logger.LogInformation($"解析域名:{address},IP:{ip}");
|
||||
_lastHostName = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +158,7 @@ namespace BITKit.Net
|
||||
|
||||
|
||||
IsConnecting = true;
|
||||
if (client.connected) return false;
|
||||
if (_client.connected) return false;
|
||||
await BITApp.SwitchToMainThread();
|
||||
OnStartConnect?.Invoke();
|
||||
await UniTask.SwitchToThreadPool();
|
||||
@@ -151,7 +166,7 @@ namespace BITKit.Net
|
||||
{
|
||||
_lastHeartbeat = DateTime.Now;
|
||||
|
||||
client.Connect(address, port);
|
||||
_client.Connect(address, port);
|
||||
|
||||
_timer.Start();
|
||||
_interval = TimeSpan.FromMilliseconds(_timer.Interval);
|
||||
@@ -163,13 +178,13 @@ namespace BITKit.Net
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
client.Send(new[] { (byte)NetCommandType.Heartbeat }, KcpChannel.Reliable);
|
||||
_client.Send(new[] { (byte)NetCommandType.Heartbeat }, KcpChannel.Reliable);
|
||||
Traffic += new float2(1, 0);
|
||||
client.Tick();
|
||||
_client.Tick();
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
if (client.connected)
|
||||
if (_client.connected)
|
||||
{
|
||||
SendServerMessage(Environment.MachineName);
|
||||
|
||||
@@ -177,11 +192,11 @@ namespace BITKit.Net
|
||||
|
||||
_connectedAddress = address;
|
||||
_connectedPort = port;
|
||||
return client.connected;
|
||||
return _client.connected;
|
||||
}
|
||||
|
||||
OnConnectedFailed?.Invoke();
|
||||
Disconnect();
|
||||
DisconnectInternal();
|
||||
|
||||
IsConnecting = false;
|
||||
return false;
|
||||
@@ -220,7 +235,7 @@ namespace BITKit.Net
|
||||
switch (type)
|
||||
{
|
||||
case NetCommandType.Message:
|
||||
BIT4Log.Log<KcpNetClient>($"已收到消息:{reader.ReadString()}");
|
||||
_logger.LogInformation($"已收到消息:{reader.ReadString()}");
|
||||
break;
|
||||
case NetCommandType.AllClientCommand:
|
||||
case NetCommandType.Command:
|
||||
@@ -424,7 +439,7 @@ namespace BITKit.Net
|
||||
|
||||
if (eventDelegate is null)
|
||||
{
|
||||
BIT4Log.Warning<KcpNetClient>($"未找到对应的事件:{rpcName}");
|
||||
//BIT4Log.Warning<KcpNetClient>($"未找到对应的事件:{rpcName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -443,9 +458,9 @@ namespace BITKit.Net
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BIT4Log.Log<KcpNetClient>($"未知消息类型:{type},字节:{(byte)type}");
|
||||
_logger.LogInformation($"未知消息类型:{type},字节:{(byte)type}");
|
||||
if (bytes.Array != null)
|
||||
BIT4Log.Log<KcpNetClient>(
|
||||
_logger.LogInformation(
|
||||
$"已收到:({Id}, {BitConverter.ToString(bytes.Array, bytes.Offset, bytes.Count)} @ {channel})");
|
||||
break;
|
||||
}
|
||||
@@ -456,17 +471,17 @@ namespace BITKit.Net
|
||||
// if (BITApp.SynchronizationContext is not null)
|
||||
// await UniTask.SwitchToSynchronizationContext(BITApp.SynchronizationContext);
|
||||
// OnConnected?.Invoke();
|
||||
// BIT4Log.Log<KcpNetClient>("已连接");
|
||||
// _logger.LogInformation("已连接");
|
||||
}
|
||||
|
||||
private async void OnDisconnectInternal()
|
||||
{
|
||||
//BIT4Log.Log<KcpNetClient>("连接被断开");
|
||||
Disconnect();
|
||||
// _logger.LogInformation("连接被断开");
|
||||
DisconnectInternal();
|
||||
}
|
||||
private void OnError(ErrorCode errorCode, string message)
|
||||
{
|
||||
BIT4Log.Log<KcpNetClient>($"{client.remoteEndPoint}异常:{errorCode},{message}");
|
||||
_logger.LogInformation($"{_client.remoteEndPoint}异常:{errorCode},{message}");
|
||||
}
|
||||
|
||||
public void ServerCommand<T>(T command = default)
|
||||
@@ -500,6 +515,10 @@ namespace BITKit.Net
|
||||
|
||||
public async UniTask<T> GetFromServer<T>(string path = default,params object[] pars)
|
||||
{
|
||||
if (IsConnected is false)
|
||||
{
|
||||
throw new NetOfflineException();
|
||||
}
|
||||
//await UniTask.SwitchToThreadPool();
|
||||
var id = _index++;
|
||||
var ms = new MemoryStream();
|
||||
@@ -528,6 +547,10 @@ namespace BITKit.Net
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (IsConnected is false)
|
||||
{
|
||||
throw new NetOfflineException();
|
||||
}
|
||||
if ((_now - startTime).TotalSeconds > RpcTimeOut)
|
||||
{
|
||||
await BITApp.SwitchToMainThread();
|
||||
@@ -573,24 +596,25 @@ namespace BITKit.Net
|
||||
foreach (var methodInfo in rpcHandle.GetType().GetMethods())
|
||||
{
|
||||
var att = methodInfo.GetCustomAttribute<NetRpcAttribute>();
|
||||
if(att is null)continue;
|
||||
if (att is null) continue;
|
||||
_rpcMethods.AddOrUpdate(methodInfo.Name, methodInfo, (s, info) => methodInfo);
|
||||
_rpcHandles.AddOrUpdate(methodInfo.Name, rpcHandle, (s, o) => rpcHandle);
|
||||
|
||||
reportBuilder.AppendLine($"Add [{methodInfo.Name}] as MethodInfo");
|
||||
}
|
||||
|
||||
foreach (var eventInfo in rpcHandle.GetType().GetEvents())
|
||||
{
|
||||
var att = eventInfo.GetCustomAttribute<NetRpcAttribute>();
|
||||
if(att is null)continue;
|
||||
|
||||
if (att is null) continue;
|
||||
|
||||
_rpcEvents.TryAdd(eventInfo.Name, eventInfo);
|
||||
_rpcHandles.TryAdd(eventInfo.Name, rpcHandle);
|
||||
|
||||
|
||||
reportBuilder.AppendLine($"Add [{eventInfo.Name}] as EventInfo");
|
||||
}
|
||||
|
||||
BIT4Log.Log<KcpNetClient>(reportBuilder);
|
||||
|
||||
_logger.LogInformation(reportBuilder.ToString());
|
||||
}
|
||||
|
||||
public void AddCommandListener<T>(Action<T> handle)
|
||||
@@ -621,6 +645,10 @@ namespace BITKit.Net
|
||||
|
||||
public void SendRT(string rpcName, params object[] pars)
|
||||
{
|
||||
if (IsConnected is false)
|
||||
{
|
||||
throw new NetOfflineException();
|
||||
}
|
||||
using var ms = new MemoryStream();
|
||||
using var writer = new BinaryWriter(ms);
|
||||
writer.Write((byte)NetCommandType.GetFromServer);
|
||||
@@ -650,36 +678,36 @@ namespace BITKit.Net
|
||||
.Write(message)
|
||||
.Build();
|
||||
Traffic+=new float2(bytes.Length,0);
|
||||
client.Send(bytes, KcpChannel.Reliable);
|
||||
_client.Send(bytes, KcpChannel.Reliable);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private readonly IntervalUpdate _pingInterval = new(1);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
_now = DateTime.Now;
|
||||
if(_userConnected is false)return;
|
||||
try
|
||||
{
|
||||
_now = DateTime.UtcNow;
|
||||
|
||||
|
||||
if (client.connected)
|
||||
if (_client.connected)
|
||||
{
|
||||
if (DateTime.Now - _lastHeartbeat > TimeSpan.FromSeconds(5))
|
||||
{
|
||||
BIT4Log.Warning<KcpNetClient>("心跳超时,自动断开");
|
||||
Disconnect();
|
||||
DisconnectInternal();
|
||||
_commandQueue.Clear();
|
||||
return;
|
||||
}
|
||||
while (_commandQueue.TryDequeue(out var bytes))
|
||||
{
|
||||
Traffic += new float2(bytes.Length, 0);
|
||||
client.Send(bytes, KcpChannel.Reliable);
|
||||
_client.Send(bytes, KcpChannel.Reliable);
|
||||
}
|
||||
Traffic+=new float2(1,0);
|
||||
client.Send(_heartBeat, KcpChannel.Unreliable);
|
||||
_client.Send(_heartBeat, KcpChannel.Unreliable);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -696,16 +724,7 @@ namespace BITKit.Net
|
||||
//BIT4Log.Warning<KcpNetClient>("连接已断开,清空指令队列");
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (_pingInterval.AllowUpdate)
|
||||
{
|
||||
_lastPingTime = DateTime.Now;
|
||||
client.Send(new[] { (byte)NetCommandType.Ping }, KcpChannel.Reliable);
|
||||
}
|
||||
#endif
|
||||
|
||||
client.Tick();
|
||||
_client.Tick();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -718,7 +737,7 @@ namespace BITKit.Net
|
||||
{
|
||||
// send client to server
|
||||
Traffic+=new float2(2,0);
|
||||
client.Send(new byte[]{0x01, 0x02}, KcpChannel.Reliable);
|
||||
_client.Send(new byte[]{0x01, 0x02}, KcpChannel.Reliable);
|
||||
}
|
||||
}
|
||||
}
|
@@ -101,7 +101,7 @@ namespace BITKit.Net
|
||||
BIT4Log.Log<KCPNetServer>($"{Name}:链接{id}超时,已断开");
|
||||
}
|
||||
|
||||
if (server.IsActive() is false || ManualTick) return;
|
||||
if (server.IsActive() is false) return;
|
||||
|
||||
server.Tick();
|
||||
|
||||
@@ -150,9 +150,11 @@ namespace BITKit.Net
|
||||
_timer.Interval = 1000f / TickRate;
|
||||
_interval = TimeSpan.FromSeconds(1.0 / TickRate);
|
||||
}
|
||||
|
||||
OnStartServer?.Invoke();
|
||||
server.Start(port);
|
||||
_timer.Start();
|
||||
if (ManualTick is false)
|
||||
_timer.Start();
|
||||
_isStarted = true;
|
||||
BIT4Log.Log<KCPNetServer>($"已启动KCP服务器:{port}");
|
||||
}
|
||||
@@ -551,14 +553,14 @@ namespace BITKit.Net
|
||||
{
|
||||
foreach (var methodInfo in rpcHandle.GetType().GetMethods())
|
||||
{
|
||||
var att = methodInfo.GetCustomAttribute<NetRpcAttribute>();
|
||||
var att = methodInfo.GetCustomAttribute<NetRpcAttribute>(true);
|
||||
if(att is null)continue;
|
||||
_rpcMethods.TryAdd(methodInfo.Name, methodInfo);
|
||||
_rpcHandles.TryAdd(methodInfo.Name, rpcHandle);
|
||||
}
|
||||
foreach (var eventInfo in rpcHandle.GetType().GetEvents())
|
||||
{
|
||||
var att = eventInfo.GetCustomAttribute<NetRpcAttribute>();
|
||||
var att = eventInfo.GetCustomAttribute<NetRpcAttribute>(true);
|
||||
if(att is null)continue;
|
||||
|
||||
_rpcEvents.TryAdd(eventInfo.Name, eventInfo);
|
||||
|
Reference in New Issue
Block a user