ソースを参照

加上TcpTransport超时检查

tanghai 2 年 前
コミット
3622bbaa9c

+ 1 - 0
Unity/Assets/Scripts/Core/Network/ErrorCore.cs

@@ -7,6 +7,7 @@
         
         
         public const int ERR_KcpConnectTimeout = 100205;
         public const int ERR_KcpConnectTimeout = 100205;
         public const int ERR_KcpAcceptTimeout = 100206;
         public const int ERR_KcpAcceptTimeout = 100206;
+        public const int ERR_KcpReadWriteTimeout = 100207;
         public const int ERR_PeerDisconnect = 100208;
         public const int ERR_PeerDisconnect = 100208;
         public const int ERR_SocketCantSend = 100209;
         public const int ERR_SocketCantSend = 100209;
         public const int ERR_SocketError = 100210;
         public const int ERR_SocketError = 100210;

+ 41 - 7
Unity/Assets/Scripts/Core/Network/IKcpTransport.cs

@@ -84,6 +84,10 @@ namespace ET
         private readonly DoubleMap<long, EndPoint> idEndpoints = new();
         private readonly DoubleMap<long, EndPoint> idEndpoints = new();
 
 
         private readonly Queue<(long, MemoryBuffer)> channelRecvDatas = 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)
         public TcpTransport(AddressFamily addressFamily)
         {
         {
@@ -103,33 +107,44 @@ namespace ET
         private void OnAccept(long id, IPEndPoint ipEndPoint)
         private void OnAccept(long id, IPEndPoint ipEndPoint)
         {
         {
             TChannel channel = this.tService.Get(id);
             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);
             this.idEndpoints.Add(id, channel.RemoteAddress);
         }
         }
 
 
         private void OnError(long id, int error)
         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.idEndpoints.RemoveByKey(id);
+            this.readWriteTime.Remove(id);
         }
         }
         
         
         private void OnRead(long id, MemoryBuffer memoryBuffer)
         private void OnRead(long id, MemoryBuffer memoryBuffer)
         {
         {
+            long timeNow = TimeInfo.Instance.ClientFrameTime();
+            this.readWriteTime[id] = timeNow;
             channelRecvDatas.Enqueue((id, memoryBuffer));
             channelRecvDatas.Enqueue((id, memoryBuffer));
         }
         }
         
         
         public void Send(byte[] bytes, int index, int length, EndPoint endPoint)
         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 memoryBuffer = this.tService.Fetch();
             memoryBuffer.Write(bytes, index, length);
             memoryBuffer.Write(bytes, index, length);
             memoryBuffer.Seek(0, SeekOrigin.Begin);
             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)
         public int Recv(byte[] buffer, ref EndPoint endPoint)
@@ -159,6 +174,25 @@ namespace ET
 
 
         public void Update()
         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();
             this.tService.Update();
         }
         }