|
|
@@ -84,6 +84,10 @@ namespace ET
|
|
|
private readonly DoubleMap<long, EndPoint> idEndpoints = new();
|
|
|
|
|
|
private readonly Queue<(long, MemoryBuffer)> channelRecvDatas = new();
|
|
|
+
|
|
|
+ private readonly Dictionary<long, long> readWriteTime = new();
|
|
|
+
|
|
|
+ private readonly Queue<long> channelIds = new();
|
|
|
|
|
|
public TcpTransport(AddressFamily addressFamily)
|
|
|
{
|
|
|
@@ -103,33 +107,44 @@ namespace ET
|
|
|
private void OnAccept(long id, IPEndPoint ipEndPoint)
|
|
|
{
|
|
|
TChannel channel = this.tService.Get(id);
|
|
|
+ long timeNow = TimeInfo.Instance.ClientFrameTime();
|
|
|
+ this.readWriteTime[id] = timeNow;
|
|
|
+ this.channelIds.Enqueue(id);
|
|
|
this.idEndpoints.Add(id, channel.RemoteAddress);
|
|
|
}
|
|
|
|
|
|
private void OnError(long id, int error)
|
|
|
{
|
|
|
- Log.Error($"IKcpTransport error: {error}");
|
|
|
+ Log.Warning($"IKcpTransport tcp error: {error}");
|
|
|
+ this.tService.Remove(id, error);
|
|
|
this.idEndpoints.RemoveByKey(id);
|
|
|
+ this.readWriteTime.Remove(id);
|
|
|
}
|
|
|
|
|
|
private void OnRead(long id, MemoryBuffer memoryBuffer)
|
|
|
{
|
|
|
+ long timeNow = TimeInfo.Instance.ClientFrameTime();
|
|
|
+ this.readWriteTime[id] = timeNow;
|
|
|
channelRecvDatas.Enqueue((id, memoryBuffer));
|
|
|
}
|
|
|
|
|
|
public void Send(byte[] bytes, int index, int length, EndPoint endPoint)
|
|
|
{
|
|
|
- long channelId = this.idEndpoints.GetKeyByValue(endPoint);
|
|
|
- if (channelId == 0)
|
|
|
+ long id = this.idEndpoints.GetKeyByValue(endPoint);
|
|
|
+ if (id == 0)
|
|
|
{
|
|
|
- channelId = IdGenerater.Instance.GenerateInstanceId();
|
|
|
- this.tService.Create(channelId, endPoint.ToString());
|
|
|
- this.idEndpoints.Add(channelId, endPoint);
|
|
|
+ id = IdGenerater.Instance.GenerateInstanceId();
|
|
|
+ this.tService.Create(id, endPoint.ToString());
|
|
|
+ this.idEndpoints.Add(id, endPoint);
|
|
|
+ this.channelIds.Enqueue(id);
|
|
|
}
|
|
|
MemoryBuffer memoryBuffer = this.tService.Fetch();
|
|
|
memoryBuffer.Write(bytes, index, length);
|
|
|
memoryBuffer.Seek(0, SeekOrigin.Begin);
|
|
|
- this.tService.Send(channelId, memoryBuffer);
|
|
|
+ this.tService.Send(id, memoryBuffer);
|
|
|
+
|
|
|
+ long timeNow = TimeInfo.Instance.ClientFrameTime();
|
|
|
+ this.readWriteTime[id] = timeNow;
|
|
|
}
|
|
|
|
|
|
public int Recv(byte[] buffer, ref EndPoint endPoint)
|
|
|
@@ -159,6 +174,25 @@ namespace ET
|
|
|
|
|
|
public void Update()
|
|
|
{
|
|
|
+ // 检查长时间不读写的TChannel, 超时断开, 一次update检查10个
|
|
|
+ long timeNow = TimeInfo.Instance.ClientFrameTime();
|
|
|
+ const int MaxCheckNum = 10;
|
|
|
+ int n = this.channelIds.Count < MaxCheckNum? this.channelIds.Count : MaxCheckNum;
|
|
|
+ for (int i = 0; i < n; ++i)
|
|
|
+ {
|
|
|
+ long id = this.channelIds.Dequeue();
|
|
|
+ if (!this.readWriteTime.TryGetValue(id, out long rwTime))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (timeNow - rwTime > 30 * 1000)
|
|
|
+ {
|
|
|
+ this.OnError(id, ErrorCore.ERR_KcpReadWriteTimeout);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ this.channelIds.Enqueue(id);
|
|
|
+ }
|
|
|
+
|
|
|
this.tService.Update();
|
|
|
}
|
|
|
|