Ver Fonte

KCP同时使用TCP跟UDP,调通!

tanghai há 2 anos atrás
pai
commit
12f3caccf8
24 ficheiros alterados com 239 adições e 285 exclusões
  1. 1 1
      Unity/Assets/Scripts/Core/Network/AService.cs
  2. 0 67
      Unity/Assets/Scripts/Core/Network/Extensions.cs
  3. 0 11
      Unity/Assets/Scripts/Core/Network/Extensions.cs.meta
  4. 5 16
      Unity/Assets/Scripts/Core/Network/IKcpTransport.cs
  5. 2 6
      Unity/Assets/Scripts/Core/Network/KChannel.cs
  6. 46 28
      Unity/Assets/Scripts/Core/Network/KService.cs
  7. 1 0
      Unity/Assets/Scripts/Core/Network/NetServices.cs
  8. 0 1
      Unity/Assets/Scripts/Core/Network/TChannel.cs
  9. 2 1
      Unity/Assets/Scripts/Core/World/Module/Log/Log.cs
  10. 1 1
      Unity/Assets/Scripts/Core/World/Module/Options/Options.cs
  11. 6 3
      Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Main2NetClient_LoginHandler.cs
  12. 1 1
      Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Ping/PingComponentSystem.cs
  13. 3 1
      Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Router/RouterCheckComponentSystem.cs
  14. 88 67
      Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Router/RouterHelper.cs
  15. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Benchmark/FiberInit_BenchmarkClient.cs
  16. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Benchmark/FiberInit_BenchmarkServer.cs
  17. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Demo/Gate/FiberInit_Gate.cs
  18. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Demo/Realm/FiberInit_Realm.cs
  19. 1 1
      Unity/Assets/Scripts/Hotfix/Server/Module/Message/ProcessOuterSenderSystem.cs
  20. 71 69
      Unity/Assets/Scripts/Hotfix/Server/Module/Router/RouterComponentSystem.cs
  21. 4 4
      Unity/Assets/Scripts/Hotfix/Share/Module/Message/NetComponentSystem.cs
  22. 1 0
      Unity/Assets/Scripts/Model/Server/Module/Router/RouterNode.cs
  23. 2 2
      Unity/Assets/Scripts/Model/Share/Module/Message/NetComponent.cs
  24. 0 1
      Unity/Assets/Scripts/Model/Share/Module/Message/Session.cs

+ 1 - 1
Unity/Assets/Scripts/Core/Network/AService.cs

@@ -14,7 +14,7 @@ namespace ET
         public long Id { get; set; }
         
         public ServiceType ServiceType { get; protected set; }
-
+        
         private const int MaxMemoryBufferSize = 1024;
 		
         private readonly Queue<MemoryBuffer> pool = new();

+ 0 - 67
Unity/Assets/Scripts/Core/Network/Extensions.cs

@@ -1,67 +0,0 @@
-using System.Net;
-using System.Net.Sockets;
-
-namespace ET
-{
-    public static class Extensions
-    {
-        // always pass the same IPEndPointNonAlloc instead of allocating a new
-        // one each time.
-        //
-        // use IPEndPointNonAlloc.temp to get the latest SocketAdddress written
-        // by ReceiveFrom_Internal!
-        //
-        // IMPORTANT: .temp will be overwritten in next call!
-        //            hash or manually copy it if you need to store it, e.g.
-        //            when adding a new connection.
-        public static int ReceiveFrom_NonAlloc(
-            this Socket socket,
-            byte[] buffer,
-            int offset,
-            int size,
-            SocketFlags socketFlags,
-            EndPoint remoteEndPoint)
-        {
-            // call ReceiveFrom with IPEndPointNonAlloc.
-            // need to wrap this in ReceiveFrom_NonAlloc because it's not
-            // obvious that IPEndPointNonAlloc.Create does NOT create a new
-            // IPEndPoint. it saves the result in IPEndPointNonAlloc.temp!
-#if UNITY
-            EndPoint casted = remoteEndPoint;
-            return  socket.ReceiveFrom(buffer, offset, size, socketFlags, ref casted);
-#else
-            return  socket.ReceiveFrom(buffer, offset, size, socketFlags, ref remoteEndPoint);
-#endif
-        }
-
-        // same as above, different parameters
-        public static int ReceiveFrom_NonAlloc(this Socket socket, byte[] buffer, ref EndPoint remoteEndPoint)
-        {
-#if UNITY
-            EndPoint casted = remoteEndPoint;
-            return socket.ReceiveFrom(buffer, ref casted);
-#else
-            return socket.ReceiveFrom(buffer, ref remoteEndPoint);
-#endif
-
-        }
-        
-        // SendTo allocates too:
-        // https://github.com/mono/mono/blob/f74eed4b09790a0929889ad7fc2cf96c9b6e3757/mcs/class/System/System.Net.Sockets/Socket.cs#L2240
-        // -> the allocation is in EndPoint.Serialize()
-        // NOTE: technically this function isn't necessary.
-        //       could just pass IPEndPointNonAlloc.
-        //       still good for strong typing.
-        //public static int SendTo_NonAlloc(
-        //    this Socket socket,
-        //    byte[] buffer,
-        //    int offset,
-        //    int size,
-        //    SocketFlags socketFlags,
-        //    IPEndPointNonAlloc remoteEndPoint)
-        //{
-        //    EndPoint casted = remoteEndPoint;
-        //    return socket.SendTo(buffer, offset, size, socketFlags, casted);
-        //}
-    }
-}

+ 0 - 11
Unity/Assets/Scripts/Core/Network/Extensions.cs.meta

@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: b60b6ed73c53bbd489c9a3f958c72722
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 5 - 16
Unity/Assets/Scripts/Core/Network/IKcpTransport.cs

@@ -11,7 +11,6 @@ namespace ET
     {
         void Send(byte[] bytes, int index, int length, EndPoint endPoint);
         int Recv(byte[] buffer, ref EndPoint endPoint);
-        int RecvNonAlloc(byte[] buffer, ref EndPoint endPoint);
         int Available();
         void Update();
     }
@@ -57,11 +56,6 @@ namespace ET
             return this.socket.ReceiveFrom(buffer, ref endPoint);
         }
 
-        public int RecvNonAlloc(byte[] buffer, ref EndPoint endPoint)
-        {
-            return this.socket.ReceiveFrom_NonAlloc(buffer, ref endPoint);
-        }
-
         public int Available()
         {
             return this.socket.Available;
@@ -83,7 +77,7 @@ namespace ET
 
         private readonly DoubleMap<long, EndPoint> idEndpoints = new();
 
-        private readonly Queue<(long, MemoryBuffer)> channelRecvDatas = new();
+        private readonly Queue<(EndPoint, MemoryBuffer)> channelRecvDatas = new();
 
         private readonly Dictionary<long, long> readWriteTime = new();
 
@@ -125,7 +119,8 @@ namespace ET
         {
             long timeNow = TimeInfo.Instance.ClientFrameTime();
             this.readWriteTime[id] = timeNow;
-            channelRecvDatas.Enqueue((id, memoryBuffer));
+            TChannel channel = this.tService.Get(id);
+            channelRecvDatas.Enqueue((channel.RemoteAddress, memoryBuffer));
         }
         
         public void Send(byte[] bytes, int index, int length, EndPoint endPoint)
@@ -154,14 +149,8 @@ namespace ET
 
         public int RecvNonAlloc(byte[] buffer, ref EndPoint endPoint)
         {
-            (long channelId, MemoryBuffer memoryBuffer) = this.channelRecvDatas.Dequeue();
-            TChannel channel = this.tService.Get(channelId);
-            if (channel == null)
-            {
-                return 0;
-            }
-            
-            endPoint = channel.RemoteAddress;
+            (EndPoint e, MemoryBuffer memoryBuffer) = this.channelRecvDatas.Dequeue();
+            endPoint = e;
             int count = memoryBuffer.Read(buffer);
             this.tService.Recycle(memoryBuffer);
             return count;

+ 2 - 6
Unity/Assets/Scripts/Core/Network/KChannel.cs

@@ -200,7 +200,7 @@ namespace ET
 				buffer.WriteTo(0, KcpProtocalType.SYN);
 				buffer.WriteTo(1, this.LocalConn);
 				buffer.WriteTo(5, this.RemoteConn);
-				this.Service.Socket.Send(buffer, 0, 9, this.RemoteAddress);
+				this.Service.Transport.Send(buffer, 0, 9, this.RemoteAddress);
 				// 这里很奇怪 调用socket.LocalEndPoint会动到this.RemoteAddressNonAlloc里面的temp,这里就不仔细研究了
 				Log.Info($"kchannel connect {this.LocalConn} {this.RemoteConn} {this.RealAddress}");
 
@@ -373,7 +373,7 @@ namespace ET
 				bytes.WriteTo(0, KcpProtocalType.MSG);
 				// 每个消息头部写下该channel的id;
 				bytes.WriteTo(1, this.LocalConn);
-				this.Service.Socket.Send(bytes, 0, count + 5, this.RemoteAddress);
+				this.Service.Transport.Send(bytes, 0, count + 5, this.RemoteAddress);
 			}
 			catch (Exception e)
 			{
@@ -428,12 +428,10 @@ namespace ET
 				this.waitSendMessages.Enqueue(memoryBuffer);
 				return;
 			}
-
 			if (this.kcp == null)
 			{
 				throw new Exception("kchannel connected but kcp is zero!");
 			}
-			
 			// 检查等待发送的消息,如果超出最大等待大小,应该断开连接
 			int n = this.kcp.WaitSnd;
 			int maxWaitSize = 0;
@@ -455,9 +453,7 @@ namespace ET
 				this.OnError(ErrorCore.ERR_KcpWaitSendSizeTooLarge);
 				return;
 			}
-
 			this.KcpSend(memoryBuffer);
-			
 			this.Service.Recycle(memoryBuffer);
 		}
 		

+ 46 - 28
Unity/Assets/Scripts/Core/Network/KService.cs

@@ -40,24 +40,49 @@ namespace ET
         {
             get
             {
-                return (uint)((DateTime.UtcNow.Ticks - this.startTime) / 10000);
+                return (uint)(TimeInfo.Instance.ClientFrameTime() - this.startTime);
             }
         }
 
-        public IKcpTransport Socket;
+        public IKcpTransport Transport;
+        
+        public NetworkProtocol Protocol { get; set; }
 
-        public KService(IPEndPoint ipEndPoint, ServiceType serviceType)
+        public KService(IPEndPoint ipEndPoint, ServiceType serviceType, NetworkProtocol protocol)
         {
             this.ServiceType = serviceType;
-            this.startTime = DateTime.UtcNow.Ticks;
-            this.Socket = new TcpTransport(ipEndPoint);
+            this.startTime = TimeInfo.Instance.ClientFrameTime();
+            this.Protocol = protocol;
+            switch (this.Protocol)
+            {
+                case NetworkProtocol.TCP:
+                    this.Transport = new TcpTransport(ipEndPoint);
+                    break;
+                case NetworkProtocol.UDP:
+                    this.Transport = new UdpTransport(ipEndPoint);
+                    break;
+                default:
+                    throw new ArgumentOutOfRangeException($"{this.Protocol}");
+            }
         }
 
-        public KService(AddressFamily addressFamily, ServiceType serviceType)
+        public KService(AddressFamily addressFamily, ServiceType serviceType, NetworkProtocol protocol)
         {
             this.ServiceType = serviceType;
-            this.startTime = DateTime.UtcNow.Ticks;
-            this.Socket = new TcpTransport(addressFamily);
+            this.startTime = TimeInfo.Instance.ClientFrameTime();
+            this.Transport = new TcpTransport(addressFamily);
+            this.Protocol = protocol;
+            switch (this.Protocol)
+            {
+                case NetworkProtocol.TCP:
+                    this.Transport = new TcpTransport(addressFamily);
+                    break;
+                case NetworkProtocol.UDP:
+                    this.Transport = new UdpTransport(addressFamily);
+                    break;
+                default:
+                    throw new ArgumentOutOfRangeException($"{this.Protocol}");
+            }
         }
 
         // 保存所有的channel
@@ -67,8 +92,6 @@ namespace ET
         private readonly byte[] cache = new byte[2048];
         
         private EndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 0);
-
-
         
 
         private readonly List<long> cacheIds = new();
@@ -90,7 +113,7 @@ namespace ET
         
         public override bool IsDisposed()
         {
-            return this.Socket == null;
+            return this.Transport == null;
         }
 
         public override void Dispose()
@@ -107,8 +130,8 @@ namespace ET
                 this.Remove(channelId);
             }
 
-            this.Socket.Dispose();
-            this.Socket = null;
+            this.Transport.Dispose();
+            this.Transport = null;
         }
 
         public override (uint, uint) GetChannelConn(long channelId)
@@ -133,14 +156,14 @@ namespace ET
 
         private void Recv()
         {
-            if (this.Socket == null)
+            if (this.Transport == null)
             {
                 return;
             }
 
-            while (this.Socket != null && this.Socket.Available() > 0)
+            while (this.Transport != null && this.Transport.Available() > 0)
             {
-                int messageLength = this.Socket.RecvNonAlloc(this.cache, ref this.ipEndPoint);
+                int messageLength = this.Transport.Recv(this.cache, ref this.ipEndPoint);
                 // 长度小于1,不是正常的消息
                 if (messageLength < 1)
                 {
@@ -149,7 +172,6 @@ namespace ET
 
                 // accept
                 byte flag = this.cache[0];
-                
                 // conn从100开始,如果为1,2,3则是特殊包
                 uint remoteConn = 0;
                 uint localConn = 0;
@@ -203,7 +225,7 @@ namespace ET
                                 buffer.WriteTo(0, KcpProtocalType.RouterReconnectACK);
                                 buffer.WriteTo(1, kChannel.LocalConn);
                                 buffer.WriteTo(5, kChannel.RemoteConn);
-                                this.Socket.Send(buffer, 0, 9, this.ipEndPoint);
+                                this.Transport.Send(buffer, 0, 9, this.ipEndPoint);
                             }
                             catch (Exception e)
                             {
@@ -269,9 +291,9 @@ namespace ET
                                 buffer.WriteTo(0, KcpProtocalType.ACK);
                                 buffer.WriteTo(1, kChannel.LocalConn);
                                 buffer.WriteTo(5, kChannel.RemoteConn);
-                                Log.Info($"kservice syn: {kChannel.Id} {remoteConn} {localConn}");
+                                Log.Info($"kservice syn: {kChannel.Id} {remoteConn} {localConn} {kChannel.RemoteAddress}");
                                 
-                                this.Socket.Send(buffer, 0, 9, kChannel.RemoteAddress);
+                                this.Transport.Send(buffer, 0, 9, kChannel.RemoteAddress);
                             }
                             catch (Exception e)
                             {
@@ -344,20 +366,17 @@ namespace ET
                                 this.Disconnect(localConn, remoteConn, ErrorCore.ERR_KcpNotFoundChannel, this.ipEndPoint, 1);
                                 break;
                             }
-                            
                             // 校验remoteConn,防止第三方攻击
                             if (kChannel.RemoteConn != remoteConn)
                             {
                                 break;
                             }
-
                             // 对方发来msg,说明kchannel连接完成
                             if (!kChannel.IsConnected)
                             {
                                 kChannel.IsConnected = true;
                                 this.waitAcceptChannels.Remove(kChannel.RemoteConn);
                             }
-
                             kChannel.HandleRecv(this.cache, 5, messageLength - 5);
                             break;
                     }
@@ -406,7 +425,7 @@ namespace ET
 
             kChannel.Error = error;
             
-            Log.Info($"kservice remove channel: {id} {kChannel.LocalConn} {kChannel.RemoteConn} {error}");
+            Log.Trace($"kservice remove channel: {id} {kChannel.LocalConn} {kChannel.RemoteConn} {error}");
             this.localConnChannels.Remove(kChannel.LocalConn);
             if (this.waitAcceptChannels.TryGetValue(kChannel.RemoteConn, out KChannel waitChannel))
             {
@@ -423,7 +442,7 @@ namespace ET
         {
             try
             {
-                if (this.Socket == null)
+                if (this.Transport == null)
                 {
                     return;
                 }
@@ -435,7 +454,7 @@ namespace ET
                 buffer.WriteTo(9, (uint) error);
                 for (int i = 0; i < times; ++i)
                 {
-                    this.Socket.Send(buffer, 0, 13, address);
+                    this.Transport.Send(buffer, 0, 13, address);
                 }
             }
             catch (Exception e)
@@ -453,7 +472,6 @@ namespace ET
             {
                 return;
             }
-            
             channel.Send(memoryBuffer);
         }
 
@@ -469,7 +487,7 @@ namespace ET
 
             this.UpdateChannel(timeNow);
             
-            this.Socket.Update();
+            this.Transport.Update();
         }
 
         private void CheckWaitAcceptChannel(uint timeNow)

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

@@ -9,6 +9,7 @@ namespace ET
         TCP,
         KCP,
         Websocket,
+        UDP,
     }
 
     public class NetServices: Singleton<NetServices>, ISingletonAwake

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

@@ -135,7 +135,6 @@ namespace ET
 			}
 			
 			this.sendBuffer.Write(stream.GetBuffer(), (int)stream.Position, (int)(stream.Length - stream.Position));
-			
 			if (!this.isSending)
 			{
 				this.Service.Queue.Enqueue(new TArgs() { Op = TcpOp.StartSend, ChannelId = this.Id});

+ 2 - 1
Unity/Assets/Scripts/Core/World/Module/Log/Log.cs

@@ -93,7 +93,8 @@ namespace ET
             {
                 return;
             }
-            GetLog().Trace(ref message);
+            StackTrace st = new(1, true);
+            GetLog().Trace($"{message.ToStringAndClear()}\n{st.ToString()}");
         }
         [Conditional("DEBUG")]
         public static void Warning(ref System.Runtime.CompilerServices.DefaultInterpolatedStringHandler message)

+ 1 - 1
Unity/Assets/Scripts/Core/World/Module/Options/Options.cs

@@ -32,7 +32,7 @@ namespace ET
         [Option("Develop", Required = false, Default = 0, HelpText = "develop mode, 0正式 1开发 2压测")]
         public int Develop { get; set; }
 
-        [Option("LogLevel", Required = false, Default = 2)]
+        [Option("LogLevel", Required = false, Default = 0)]
         public int LogLevel { get; set; }
         
         [Option("Console", Required = false, Default = 0)]

+ 6 - 3
Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Main2NetClient_LoginHandler.cs

@@ -19,19 +19,22 @@ namespace ET.Client
                 routerAddressComponent =
                         root.AddComponent<RouterAddressComponent, string, int>(ConstValue.RouterHttpHost, ConstValue.RouterHttpPort);
                 await routerAddressComponent.Init();
-                root.AddComponent<NetComponent, AddressFamily>(routerAddressComponent.RouterManagerIPAddress.AddressFamily);
+                root.AddComponent<NetComponent, AddressFamily, NetworkProtocol>(routerAddressComponent.RouterManagerIPAddress.AddressFamily, NetworkProtocol.TCP);
                 root.GetComponent<FiberParentComponent>().ParentFiberId = request.OwnerFiberId;
             }
+
+            NetComponent netComponent = root.GetComponent<NetComponent>();
+            
             IPEndPoint realmAddress = routerAddressComponent.GetRealmAddress(account);
 
             R2C_Login r2CLogin;
-            using (Session session = await RouterHelper.CreateRouterSession(root, realmAddress))
+            using (Session session = await RouterHelper.CreateRouterSession(netComponent, realmAddress))
             {
                 r2CLogin = (R2C_Login)await session.Call(new C2R_Login() { Account = account, Password = password });
             }
 
             // 创建一个gate Session,并且保存到SessionComponent中
-            Session gateSession = await RouterHelper.CreateRouterSession(root, NetworkHelper.ToIPEndPoint(r2CLogin.Address));
+            Session gateSession = await RouterHelper.CreateRouterSession(netComponent, NetworkHelper.ToIPEndPoint(r2CLogin.Address));
             gateSession.AddComponent<ClientSessionErrorComponent>();
             root.AddComponent<SessionComponent>().Session = gateSession;
             G2C_LoginGate g2CLoginGate = (G2C_LoginGate)await gateSession.Call(new C2G_LoginGate() { Key = r2CLogin.Key, GateId = r2CLogin.GateId });

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Ping/PingComponentSystem.cs

@@ -51,7 +51,7 @@ namespace ET.Client
                 catch (RpcException e)
                 {
                     // session断开导致ping rpc报错,记录一下即可,不需要打成error
-                    Log.Info($"ping error: {self.Id} {e.Error}");
+                    Log.Debug($"session disconnect, ping error: {self.Id} {e.Error}");
                     return;
                 }
                 catch (Exception e)

+ 3 - 1
Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Router/RouterCheckComponentSystem.cs

@@ -20,6 +20,8 @@ namespace ET.Client
             Scene root = fiber.Root;
             
             IPEndPoint realAddress = NetworkHelper.ToIPEndPoint(self.GetParent<Session>().RemoteAddress);
+            NetComponent netComponent = root.GetComponent<NetComponent>();
+            
             while (true)
             {
                 if (self.InstanceId != instanceId)
@@ -50,7 +52,7 @@ namespace ET.Client
                     
                     Log.Info($"get recvLocalConn start: {root.Id} {realAddress} {localConn} {remoteConn}");
 
-                    (uint recvLocalConn, IPEndPoint routerAddress) = await RouterHelper.GetRouterAddress(root, realAddress, localConn, remoteConn);
+                    (uint recvLocalConn, IPEndPoint routerAddress) = await RouterHelper.GetRouterAddress(netComponent, realAddress, localConn, remoteConn);
                     if (recvLocalConn == 0)
                     {
                         Log.Error($"get recvLocalConn fail: {root.Id} {routerAddress} {realAddress} {localConn} {remoteConn}");

+ 88 - 67
Unity/Assets/Scripts/Hotfix/Client/Demo/NetClient/Router/RouterHelper.cs

@@ -7,110 +7,131 @@ namespace ET.Client
     public static partial class RouterHelper
     {
         // 注册router
-        public static async ETTask<Session> CreateRouterSession(Scene root, IPEndPoint address)
+        public static async ETTask<Session> CreateRouterSession(NetComponent netComponent, IPEndPoint address)
         {
-            (uint recvLocalConn, IPEndPoint routerAddress) = await GetRouterAddress(root, address, 0, 0);
+            (uint recvLocalConn, IPEndPoint routerAddress) = await GetRouterAddress(netComponent, address, 0, 0);
 
             if (recvLocalConn == 0)
             {
-                throw new Exception($"get router fail: {root.Id} {address}");
+                throw new Exception($"get router fail: {netComponent.Root().Id} {address}");
             }
             
             Log.Info($"get router: {recvLocalConn} {routerAddress}");
 
-            Session routerSession = root.GetComponent<NetComponent>().Create(routerAddress, address, recvLocalConn);
+            Session routerSession = netComponent.Create(routerAddress, address, recvLocalConn);
             routerSession.AddComponent<PingComponent>();
             routerSession.AddComponent<RouterCheckComponent>();
             
             return routerSession;
         }
         
-        public static async ETTask<(uint, IPEndPoint)> GetRouterAddress(Scene root, IPEndPoint address, uint localConn, uint remoteConn)
+        public static async ETTask<(uint, IPEndPoint)> GetRouterAddress(NetComponent netComponent, IPEndPoint address, uint localConn, uint remoteConn)
         {
-            Log.Info($"start get router address: {root.Id} {address} {localConn} {remoteConn}");
+            Log.Info($"start get router address: {netComponent.Root().Id} {address} {localConn} {remoteConn}");
             //return (RandomHelper.RandUInt32(), address);
-            RouterAddressComponent routerAddressComponent = root.GetComponent<RouterAddressComponent>();
+            RouterAddressComponent routerAddressComponent = netComponent.Root().GetComponent<RouterAddressComponent>();
             IPEndPoint routerInfo = routerAddressComponent.GetAddress();
             
-            uint recvLocalConn = await Connect(root, routerInfo, address, localConn, remoteConn);
+            uint recvLocalConn = await Connect(netComponent, routerInfo, address, localConn, remoteConn);
             
-            Log.Info($"finish get router address: {root.Id} {address} {localConn} {remoteConn} {recvLocalConn} {routerInfo}");
+            Log.Info($"finish get router address: {netComponent.Root().Id} {address} {localConn} {remoteConn} {recvLocalConn} {routerInfo}");
             return (recvLocalConn, routerInfo);
         }
 
         // 向router申请
-        private static async ETTask<uint> Connect(Scene root, IPEndPoint routerAddress, IPEndPoint realAddress, uint localConn, uint remoteConn)
+        private static async ETTask<uint> Connect(NetComponent netComponent, IPEndPoint routerAddress, IPEndPoint realAddress, uint localConn, uint remoteConn)
         {
-            uint connectId = RandomGenerator.RandUInt32();
-            
-            using Socket socket = new Socket(routerAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
-            
-            int count = 20;
-            byte[] sendCache = new byte[512];
-            byte[] recvCache = new byte[512];
-
-            uint synFlag;
-            if (localConn == 0)
+            IKcpTransport iKcpTransport = null;
+            try
             {
-                synFlag = KcpProtocalType.RouterSYN;
-                localConn = RandomGenerator.RandUInt32();
-            }
-            else
-            {
-                synFlag = KcpProtocalType.RouterReconnectSYN;
-            }
-            sendCache.WriteTo(0, synFlag);
-            sendCache.WriteTo(1, localConn);
-            sendCache.WriteTo(5, remoteConn);
-            byte[] addressBytes = realAddress.ToString().ToByteArray();
-            Array.Copy(addressBytes, 0, sendCache, 9, addressBytes.Length);
-            Fiber fiber = root.Fiber;
-            Log.Info($"router connect: {connectId} {localConn} {remoteConn} {routerAddress} {realAddress}");
-                
-            EndPoint recvIPEndPoint = new IPEndPoint(IPAddress.Any, 0);
+                NetworkProtocol protocol = ((KService)netComponent.AService).Protocol;
+                switch (protocol)
+                {
+                    case NetworkProtocol.TCP:
+                        iKcpTransport = new TcpTransport(routerAddress.AddressFamily);
+                        break;
+                    case NetworkProtocol.UDP:
+                        iKcpTransport = new UdpTransport(routerAddress.AddressFamily);
+                        break;
+                    default:
+                        throw new ArgumentOutOfRangeException();
+                }
 
-            long lastSendTimer = 0;
+                int count = 20;
+                byte[] sendCache = new byte[512];
+                byte[] recvCache = new byte[512];
 
-            while (true)
-            {
-                long timeNow = TimeInfo.Instance.ClientFrameTime();
-                if (timeNow - lastSendTimer > 300)
+                uint synFlag;
+                if (localConn == 0)
                 {
-                    if (--count < 0)
-                    {
-                        Log.Error($"router connect timeout fail! {localConn} {remoteConn} {routerAddress} {realAddress}");
-                        return 0;
-                    }
-                    lastSendTimer = timeNow;
-                    // 发送
-                    socket.SendTo(sendCache, 0, addressBytes.Length + 9, SocketFlags.None, routerAddress);
+                    synFlag = KcpProtocalType.RouterSYN;
+                    localConn = RandomGenerator.RandUInt32();
                 }
-                    
-                await fiber.TimerComponent.WaitFrameAsync();
-                    
-                // 接收
-                if (socket.Available > 0)
+                else
                 {
-                    int messageLength = socket.ReceiveFrom(recvCache, ref recvIPEndPoint);
-                    if (messageLength != 9)
+                    synFlag = KcpProtocalType.RouterReconnectSYN;
+                }
+
+                sendCache.WriteTo(0, synFlag);
+                sendCache.WriteTo(1, localConn);
+                sendCache.WriteTo(5, remoteConn);
+                byte[] addressBytes = realAddress.ToString().ToByteArray();
+                Array.Copy(addressBytes, 0, sendCache, 9, addressBytes.Length);
+                Fiber fiber = netComponent.Fiber();
+                Log.Info($"router connect: {localConn} {remoteConn} {routerAddress} {realAddress}");
+
+                EndPoint recvIPEndPoint = new IPEndPoint(IPAddress.Any, 0);
+
+                long lastSendTimer = 0;
+
+                while (true)
+                {
+                    iKcpTransport.Update();
+                    
+                    long timeNow = TimeInfo.Instance.ClientFrameTime();
+                    if (timeNow - lastSendTimer > 300)
                     {
-                        Log.Error($"router connect error1: {connectId} {messageLength} {localConn} {remoteConn} {routerAddress} {realAddress}");
-                        continue;
+                        if (--count < 0)
+                        {
+                            Log.Error($"router connect timeout fail! {localConn} {remoteConn} {routerAddress} {realAddress}");
+                            return 0;
+                        }
+
+                        lastSendTimer = timeNow;
+                        // 发送
+                        iKcpTransport.Send(sendCache, 0, addressBytes.Length + 9, routerAddress);
                     }
 
-                    byte flag = recvCache[0];
-                    if (flag != KcpProtocalType.RouterReconnectACK && flag != KcpProtocalType.RouterACK)
+                    await fiber.TimerComponent.WaitFrameAsync();
+                    
+                    // 接收
+                    if (iKcpTransport.Available() > 0)
                     {
-                        Log.Error($"router connect error2: {connectId} {synFlag} {flag} {localConn} {remoteConn} {routerAddress} {realAddress}");
-                        continue;
-                    }
+                        int messageLength = iKcpTransport.Recv(recvCache, ref recvIPEndPoint);
+                        if (messageLength != 9)
+                        {
+                            Log.Error($"router connect error1: {messageLength} {localConn} {remoteConn} {routerAddress} {realAddress}");
+                            continue;
+                        }
+
+                        byte flag = recvCache[0];
+                        if (flag != KcpProtocalType.RouterReconnectACK && flag != KcpProtocalType.RouterACK)
+                        {
+                            Log.Error($"router connect error2: {synFlag} {flag} {localConn} {remoteConn} {routerAddress} {realAddress}");
+                            continue;
+                        }
 
-                    uint recvRemoteConn = BitConverter.ToUInt32(recvCache, 1);
-                    uint recvLocalConn = BitConverter.ToUInt32(recvCache, 5);
-                    Log.Info($"router connect finish: {connectId} {recvRemoteConn} {recvLocalConn} {localConn} {remoteConn} {routerAddress} {realAddress}");
-                    return recvLocalConn;
+                        uint recvRemoteConn = BitConverter.ToUInt32(recvCache, 1);
+                        uint recvLocalConn = BitConverter.ToUInt32(recvCache, 5);
+                        Log.Info($"router connect finish: {recvRemoteConn} {recvLocalConn} {localConn} {remoteConn} {routerAddress} {realAddress}");
+                        return recvLocalConn;
+                    }
                 }
             }
+            finally
+            {
+                iKcpTransport?.Dispose();
+            }
         }
     }
 }

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Benchmark/FiberInit_BenchmarkClient.cs

@@ -18,7 +18,7 @@ namespace ET.Server
             //root.AddComponent<GateSessionKeyComponent>();
             //root.AddComponent<LocationProxyComponent>();
             //root.AddComponent<ActorLocationSenderComponent>();
-            root.AddComponent<NetComponent, AddressFamily>(AddressFamily.InterNetwork);
+            root.AddComponent<NetComponent, AddressFamily, NetworkProtocol>(AddressFamily.InterNetwork, NetworkProtocol.UDP);
             root.AddComponent<BenchmarkClientComponent>();
             await ETTask.CompletedTask;
         }

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Benchmark/FiberInit_BenchmarkServer.cs

@@ -18,7 +18,7 @@ namespace ET.Server
             //root.AddComponent<GateSessionKeyComponent>();
             //root.AddComponent<LocationProxyComponent>();
             //root.AddComponent<ActorLocationSenderComponent>();
-            root.AddComponent<NetComponent, IPEndPoint>(StartSceneConfigCategory.Instance.Benchmark.OuterIPPort);
+            root.AddComponent<NetComponent, IPEndPoint, NetworkProtocol>(StartSceneConfigCategory.Instance.Benchmark.OuterIPPort, NetworkProtocol.UDP);
             root.AddComponent<BenchmarkServerComponent>();
             await ETTask.CompletedTask;
         }

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Demo/Gate/FiberInit_Gate.cs

@@ -19,7 +19,7 @@ namespace ET.Server
             root.AddComponent<MessageLocationSenderComponent>();
 
             StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.Get((int)root.Id);
-            root.AddComponent<NetComponent, IPEndPoint>(startSceneConfig.InnerIPPort);
+            root.AddComponent<NetComponent, IPEndPoint, NetworkProtocol>(startSceneConfig.InnerIPPort, NetworkProtocol.UDP);
             await ETTask.CompletedTask;
         }
     }

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Demo/Realm/FiberInit_Realm.cs

@@ -14,7 +14,7 @@ namespace ET.Server
             root.AddComponent<ProcessInnerSender>();
             root.AddComponent<MessageSender>();
             StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.Get(root.Fiber.Id);
-            root.AddComponent<NetComponent, IPEndPoint>(startSceneConfig.InnerIPPort);
+            root.AddComponent<NetComponent, IPEndPoint, NetworkProtocol>(startSceneConfig.InnerIPPort, NetworkProtocol.UDP);
 
             await ETTask.CompletedTask;
         }

+ 1 - 1
Unity/Assets/Scripts/Hotfix/Server/Module/Message/ProcessOuterSenderSystem.cs

@@ -19,7 +19,7 @@ namespace ET.Server
                 }
                 case NetworkProtocol.KCP:
                 {
-                    self.AService = new KService(address, ServiceType.Inner);
+                    self.AService = new KService(address, ServiceType.Inner, NetworkProtocol.UDP);
                     break;
                 }
             }

+ 71 - 69
Unity/Assets/Scripts/Hotfix/Server/Module/Router/RouterComponentSystem.cs

@@ -15,7 +15,7 @@ namespace ET.Server
         {
             self.OuterUdp = new UdpTransport(outerAddress);
             self.OuterTcp = new TcpTransport(outerAddress);
-            self.InnerSocket = new TcpTransport(new IPEndPoint(IPAddress.Parse(innerIP), 0));
+            self.InnerSocket = new UdpTransport(new IPEndPoint(IPAddress.Parse(innerIP), 0));
         }
         
         [EntitySystem]
@@ -61,7 +61,7 @@ namespace ET.Server
                 try
                 {
                     int messageLength = self.OuterTcp.Recv(self.Cache, ref self.IPEndPoint);
-                    self.RecvOuterHandler(messageLength, timeNow);
+                    self.RecvOuterHandler(messageLength, timeNow, self.OuterTcp);
                 }
                 catch (Exception e)
                 {
@@ -78,7 +78,7 @@ namespace ET.Server
                 try
                 {
                     int messageLength = self.OuterUdp.Recv(self.Cache, ref self.IPEndPoint);
-                    self.RecvOuterHandler(messageLength, timeNow);
+                    self.RecvOuterHandler(messageLength, timeNow, self.OuterUdp);
                 }
                 catch (Exception e)
                 {
@@ -131,7 +131,6 @@ namespace ET.Server
                 try
                 {
                     int messageLength = self.InnerSocket.Recv(self.Cache, ref self.IPEndPoint);
-                    
                     self.RecvInnerHandler(messageLength, timeNow);
                 }
                 catch (Exception e)
@@ -141,7 +140,7 @@ namespace ET.Server
             }
         }
 
-        private static void RecvOuterHandler(this RouterComponent self, int messageLength, long timeNow)
+        private static void RecvOuterHandler(this RouterComponent self, int messageLength, long timeNow, IKcpTransport transport)
         {
             // 长度小于1,不是正常的消息
             if (messageLength < 1)
@@ -206,7 +205,7 @@ namespace ET.Server
                         self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterRouterSyncCountTooMuchTimes);
                         break;
                     }
-
+                    routerNode.KcpTransport = transport;
                     // 转发到内网
                     self.Cache.WriteTo(0, KcpProtocalType.RouterReconnectSYN);
                     self.Cache.WriteTo(1, outerConn);
@@ -259,11 +258,11 @@ namespace ET.Server
                         Log.Warning($"router sync error2: {routerNode.OuterConn} {routerNode.InnerAddress} {outerConn} {realAddress}");
                         break;
                     }
-
+                    routerNode.KcpTransport = transport;
                     self.Cache.WriteTo(0, KcpProtocalType.RouterACK);
                     self.Cache.WriteTo(1, routerNode.InnerConn);
                     self.Cache.WriteTo(5, routerNode.OuterConn);
-                    self.OuterUdp.Send(self.Cache, 0, 9, routerNode.SyncIpEndPoint);
+                    routerNode.KcpTransport.Send(self.Cache, 0, 9, routerNode.SyncIpEndPoint);
 
                     if (!routerNode.CheckOuterCount(timeNow))
                     {
@@ -283,40 +282,41 @@ namespace ET.Server
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 5);
                     
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouter))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"kcp router syn not found outer nodes: {outerConn} {innerConn}");
                         break;
                     }
 
-                    if (++kcpRouter.SyncCount > 20)
+                    if (++routerNode.SyncCount > 20)
                     {
-                        self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterSyncCountTooMuchTimes);
+                        self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterSyncCountTooMuchTimes);
                         break;
                     }
 
                     // 校验ip,连接过程中ip不能变化
                     IPEndPoint ipEndPoint = (IPEndPoint) self.IPEndPoint;
-                    if (!Equals(kcpRouter.SyncIpEndPoint.Address, ipEndPoint.Address))
+                    if (!Equals(routerNode.SyncIpEndPoint.Address, ipEndPoint.Address))
                     {
-                        Log.Warning($"kcp router syn ip is diff3: {kcpRouter.SyncIpEndPoint.Address} {ipEndPoint.Address}");
+                        Log.Warning($"kcp router syn ip is diff3: {routerNode.SyncIpEndPoint.Address} {ipEndPoint.Address}");
                         break;
                     }
+                    routerNode.KcpTransport = transport;
                     
-                    kcpRouter.LastRecvOuterTime = timeNow;
-                    kcpRouter.OuterIpEndPoint = self.CloneAddress();
+                    routerNode.LastRecvOuterTime = timeNow;
+                    routerNode.OuterIpEndPoint = self.CloneAddress();
                     // 转发到内网, 带上客户端的地址
                     self.Cache.WriteTo(0, KcpProtocalType.SYN);
                     self.Cache.WriteTo(1, outerConn);
                     self.Cache.WriteTo(5, innerConn);
                     byte[] addressBytes = ipEndPoint.ToString().ToByteArray();
                     Array.Copy(addressBytes, 0, self.Cache, 9, addressBytes.Length);
-                    Log.Info($"kcp router syn: {outerConn} {innerConn} {kcpRouter.InnerIpEndPoint} {kcpRouter.OuterIpEndPoint}");
-                    self.InnerSocket.Send(self.Cache, 0, 9 + addressBytes.Length, kcpRouter.InnerIpEndPoint);
+                    Log.Info($"kcp router syn: {outerConn} {innerConn} {routerNode.InnerIpEndPoint} {routerNode.OuterIpEndPoint}");
+                    self.InnerSocket.Send(self.Cache, 0, 9 + addressBytes.Length, routerNode.InnerIpEndPoint);
 
-                    if (!kcpRouter.CheckOuterCount(timeNow))
+                    if (!routerNode.CheckOuterCount(timeNow))
                     {
-                        self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
+                        self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
                     }
 
                     break;
@@ -332,26 +332,27 @@ namespace ET.Server
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 1);
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 5);
 
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouter))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"kcp router outer fin not found outer nodes: {outerConn} {innerConn}");
                         break;
                     }
 
                     // 比对innerConn
-                    if (kcpRouter.InnerConn != innerConn)
+                    if (routerNode.InnerConn != innerConn)
                     {
-                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouter.Status}");
+                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {routerNode.Status}");
                         break;
                     }
+                    routerNode.KcpTransport = transport;
 
-                    kcpRouter.LastRecvOuterTime = timeNow;
-                    Log.Info($"kcp router outer fin: {outerConn} {innerConn} {kcpRouter.InnerIpEndPoint}");
-                    self.InnerSocket.Send(self.Cache, 0, messageLength, kcpRouter.InnerIpEndPoint);
+                    routerNode.LastRecvOuterTime = timeNow;
+                    Log.Info($"kcp router outer fin: {outerConn} {innerConn} {routerNode.InnerIpEndPoint}");
+                    self.InnerSocket.Send(self.Cache, 0, messageLength, routerNode.InnerIpEndPoint);
 
-                    if (!kcpRouter.CheckOuterCount(timeNow))
+                    if (!routerNode.CheckOuterCount(timeNow))
                     {
-                        self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
+                        self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
                     }
 
                     break;
@@ -368,38 +369,39 @@ namespace ET.Server
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 5); // local
 
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouter))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"kcp router msg not found outer nodes: {outerConn} {innerConn}");
                         break;
                     }
 
-                    if (kcpRouter.Status != RouterStatus.Msg)
+                    if (routerNode.Status != RouterStatus.Msg)
                     {
-                        Log.Warning($"router node status error: {innerConn} {outerConn} {kcpRouter.Status}");
+                        Log.Warning($"router node status error: {innerConn} {outerConn} {routerNode.Status}");
                         break;
                     }
 
                     // 比对innerConn
-                    if (kcpRouter.InnerConn != innerConn)
+                    if (routerNode.InnerConn != innerConn)
                     {
-                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouter.Status}");
+                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {routerNode.Status}");
                         break;
                     }
 
                     // 重连的时候,没有经过syn阶段,可能没有设置OuterIpEndPoint,重连请求Router的Socket跟发送消息的Socket不是同一个,所以udp出来的公网地址可能会变化
-                    if (!Equals(kcpRouter.OuterIpEndPoint, self.IPEndPoint))
+                    if (!Equals(routerNode.OuterIpEndPoint, self.IPEndPoint))
                     {
-                        kcpRouter.OuterIpEndPoint = self.CloneAddress();
+                        routerNode.OuterIpEndPoint = self.CloneAddress();
                     }
+                    routerNode.KcpTransport = transport;
+                    
+                    routerNode.LastRecvOuterTime = timeNow;
 
-                    kcpRouter.LastRecvOuterTime = timeNow;
-
-                    self.InnerSocket.Send(self.Cache, 0, messageLength, kcpRouter.InnerIpEndPoint);
+                    self.InnerSocket.Send(self.Cache, 0, messageLength, routerNode.InnerIpEndPoint);
 
-                    if (!kcpRouter.CheckOuterCount(timeNow))
+                    if (!routerNode.CheckOuterCount(timeNow))
                     {
-                        self.OnError(kcpRouter.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
+                        self.OnError(routerNode.Id, ErrorCore.ERR_KcpRouterTooManyPackets);
                     }
 
                     break;
@@ -423,38 +425,38 @@ namespace ET.Server
                 {
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 1);
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 5);
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"router node error: {innerConn} {outerConn}");
                         break;
                     }
 
                     // 必须校验innerConn,防止伪造
-                    if (innerConn != kcpRouterNode.InnerConn)
+                    if (innerConn != routerNode.InnerConn)
                     {
                         Log.Warning(
-                            $"router node innerConn error: {innerConn} {kcpRouterNode.InnerConn} {outerConn} {kcpRouterNode.OuterConn} {kcpRouterNode.Status}");
+                            $"router node innerConn error: {innerConn} {routerNode.InnerConn} {outerConn} {routerNode.OuterConn} {routerNode.Status}");
                         break;
                     }
 
                     // 必须校验outerConn,防止伪造
-                    if (outerConn != kcpRouterNode.OuterConn)
+                    if (outerConn != routerNode.OuterConn)
                     {
                         Log.Warning(
-                            $"router node outerConn error: {innerConn} {kcpRouterNode.InnerConn} {outerConn} {kcpRouterNode.OuterConn} {kcpRouterNode.Status}");
+                            $"router node outerConn error: {innerConn} {routerNode.InnerConn} {outerConn} {routerNode.OuterConn} {routerNode.Status}");
                         break;
                     }
 
-                    kcpRouterNode.Status = RouterStatus.Msg;
+                    routerNode.Status = RouterStatus.Msg;
 
-                    kcpRouterNode.LastRecvInnerTime = timeNow;
+                    routerNode.LastRecvInnerTime = timeNow;
 
                     // 转发出去
                     self.Cache.WriteTo(0, KcpProtocalType.RouterReconnectACK);
-                    self.Cache.WriteTo(1, kcpRouterNode.InnerConn);
-                    self.Cache.WriteTo(5, kcpRouterNode.OuterConn);
-                    Log.Info($"kcp router RouterAck: {outerConn} {innerConn} {kcpRouterNode.SyncIpEndPoint}");
-                    self.OuterTcp.Send(self.Cache, 0, 9, kcpRouterNode.SyncIpEndPoint);
+                    self.Cache.WriteTo(1, routerNode.InnerConn);
+                    self.Cache.WriteTo(5, routerNode.OuterConn);
+                    Log.Info($"kcp router RouterAck: {outerConn} {innerConn} {routerNode.SyncIpEndPoint}");
+                    routerNode.KcpTransport.Send(self.Cache, 0, 9, routerNode.SyncIpEndPoint);
                     break;
                 }
 
@@ -463,20 +465,20 @@ namespace ET.Server
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 5); // local
 
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"kcp router ack not found outer nodes: {outerConn} {innerConn}");
                         break;
                     }
                     
-                    kcpRouterNode.Status = RouterStatus.Msg;
+                    routerNode.Status = RouterStatus.Msg;
 
-                    kcpRouterNode.InnerConn = innerConn;
+                    routerNode.InnerConn = innerConn;
 
-                    kcpRouterNode.LastRecvInnerTime = timeNow;
+                    routerNode.LastRecvInnerTime = timeNow;
                     // 转发出去
-                    Log.Info($"kcp router ack: {outerConn} {innerConn} {kcpRouterNode.OuterIpEndPoint}");
-                    self.OuterTcp.Send(self.Cache, 0, messageLength, kcpRouterNode.OuterIpEndPoint);
+                    Log.Info($"kcp router ack: {outerConn} {innerConn} {routerNode.OuterIpEndPoint}");
+                    routerNode.KcpTransport.Send(self.Cache, 0, messageLength, routerNode.OuterIpEndPoint);
                     break;
                 }
                 case KcpProtocalType.FIN: // 断开
@@ -490,28 +492,28 @@ namespace ET.Server
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 1);
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 5);
 
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"kcp router inner fin not found outer nodes: {outerConn} {innerConn}");
                         break;
                     }
 
                     // 比对innerConn
-                    if (kcpRouterNode.InnerConn != innerConn)
+                    if (routerNode.InnerConn != innerConn)
                     {
-                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouterNode.Status}");
+                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {routerNode.Status}");
                         break;
                     }
 
                     // 重连,这个字段可能为空,需要客户端发送消息上来才能设置
-                    if (kcpRouterNode.OuterIpEndPoint == null)
+                    if (routerNode.OuterIpEndPoint == null)
                     {
                         break;
                     }
 
-                    kcpRouterNode.LastRecvInnerTime = timeNow;
-                    Log.Info($"kcp router inner fin: {outerConn} {innerConn} {kcpRouterNode.OuterIpEndPoint}");
-                    self.OuterTcp.Send(self.Cache, 0, messageLength, kcpRouterNode.OuterIpEndPoint);
+                    routerNode.LastRecvInnerTime = timeNow;
+                    Log.Info($"kcp router inner fin: {outerConn} {innerConn} {routerNode.OuterIpEndPoint}");
+                    routerNode.KcpTransport.Send(self.Cache, 0, messageLength, routerNode.OuterIpEndPoint);
 
                     break;
                 }
@@ -527,27 +529,27 @@ namespace ET.Server
                     uint innerConn = BitConverter.ToUInt32(self.Cache, 1); // remote
                     uint outerConn = BitConverter.ToUInt32(self.Cache, 5); // local
 
-                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode kcpRouterNode))
+                    if (!self.OuterNodes.TryGetValue(outerConn, out RouterNode routerNode))
                     {
                         Log.Warning($"kcp router inner msg not found outer nodes: {outerConn} {innerConn}");
                         break;
                     }
 
                     // 比对innerConn
-                    if (kcpRouterNode.InnerConn != innerConn)
+                    if (routerNode.InnerConn != innerConn)
                     {
-                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {kcpRouterNode.Status}");
+                        Log.Warning($"router node innerConn error: {innerConn} {outerConn} {routerNode.Status}");
                         break;
                     }
 
                     // 重连,这个字段可能为空,需要客户端发送消息上来才能设置
-                    if (kcpRouterNode.OuterIpEndPoint == null)
+                    if (routerNode.OuterIpEndPoint == null)
                     {
                         break;
                     }
 
-                    kcpRouterNode.LastRecvInnerTime = timeNow;
-                    self.OuterTcp.Send(self.Cache, 0, messageLength, kcpRouterNode.OuterIpEndPoint);
+                    routerNode.LastRecvInnerTime = timeNow;
+                    routerNode.KcpTransport.Send(self.Cache, 0, messageLength, routerNode.OuterIpEndPoint);
                     break;
                 }
             }

+ 4 - 4
Unity/Assets/Scripts/Hotfix/Share/Module/Message/NetComponentSystem.cs

@@ -8,18 +8,18 @@ namespace ET
     public static partial class NetComponentSystem
     {
         [EntitySystem]
-        private static void Awake(this NetComponent self, IPEndPoint address)
+        private static void Awake(this NetComponent self, IPEndPoint address, NetworkProtocol protocol)
         {
-            self.AService = new KService(address, ServiceType.Outer);
+            self.AService = new KService(address, ServiceType.Outer, protocol);
             self.AService.AcceptCallback = self.OnAccept;
             self.AService.ReadCallback = self.OnRead;
             self.AService.ErrorCallback = self.OnError;
         }
         
         [EntitySystem]
-        private static void Awake(this NetComponent self, AddressFamily addressFamily)
+        private static void Awake(this NetComponent self, AddressFamily addressFamily, NetworkProtocol protocol)
         {
-            self.AService = new KService(addressFamily, ServiceType.Outer);
+            self.AService = new KService(addressFamily, ServiceType.Outer, protocol);
             self.AService.ReadCallback = self.OnRead;
             self.AService.ErrorCallback = self.OnError;
         }

+ 1 - 0
Unity/Assets/Scripts/Model/Server/Module/Router/RouterNode.cs

@@ -15,6 +15,7 @@ namespace ET.Server
         public IPEndPoint InnerIpEndPoint;
         public IPEndPoint OuterIpEndPoint;
         public IPEndPoint SyncIpEndPoint;
+        public IKcpTransport KcpTransport;
         public uint OuterConn;
         public uint InnerConn;
         public long LastRecvOuterTime;

+ 2 - 2
Unity/Assets/Scripts/Model/Share/Module/Message/NetComponent.cs

@@ -10,8 +10,8 @@ namespace ET
     }
     
     [ComponentOf(typeof(Scene))]
-    public class NetComponent: Entity, IAwake<IPEndPoint>, IAwake<AddressFamily>, IDestroy, IUpdate
+    public class NetComponent: Entity, IAwake<IPEndPoint, NetworkProtocol>, IAwake<AddressFamily, NetworkProtocol>, IDestroy, IUpdate
     {
-        public AService AService;
+        public AService AService { get; set; }
     }
 }

+ 0 - 1
Unity/Assets/Scripts/Model/Share/Module/Message/Session.cs

@@ -138,7 +138,6 @@ namespace ET
             LogMsg.Instance.Debug(self.Fiber(), message);
 
             (ushort opcode, MemoryBuffer memoryBuffer) = MessageSerializeHelper.ToMemoryBuffer(self.AService, actorId, message);
-            
             self.AService.Send(self.Id, memoryBuffer);
         }
     }