Example #1
0
        // 向router申请
        private static async ETTask <uint> Connect(IPEndPoint routerAddress, IPEndPoint realAddress, uint localConn, uint remoteConn)
        {
            uint connectId = RandomHelper.RandUInt32();

            using Socket socket = new Socket(routerAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            int count = 30;

            byte[] sendCache = new byte[512];
            byte[] recvCache = new byte[512];

            uint synFlag = localConn == 0? KcpProtocalType.RouterSYN : KcpProtocalType.RouterReconnectSYN;

            sendCache.WriteTo(0, synFlag);
            sendCache.WriteTo(1, localConn);
            sendCache.WriteTo(5, remoteConn);
            sendCache.WriteTo(9, connectId);
            byte[] addressBytes = realAddress.ToString().ToByteArray();
            Array.Copy(addressBytes, 0, sendCache, 13, addressBytes.Length);

            Log.Info($"router connect: {connectId} {localConn} {remoteConn} {routerAddress} {realAddress}");

            EndPoint recvIPEndPoint = new IPEndPoint(IPAddress.Any, 0);

            long lastSendTimer = 0;

            while (true)
            {
                long timeNow = TimeHelper.ClientFrameTime();
                if (timeNow - lastSendTimer > 300)
                {
                    if (--count < 0)
                    {
                        Log.Error($"router connect timeout fail! {localConn} {remoteConn} {routerAddress} {realAddress}");
                        return(0);
                    }
                    lastSendTimer = timeNow;
                    // 发送
                    socket.SendTo(sendCache, 0, addressBytes.Length + 13, SocketFlags.None, routerAddress);
                }

                await TimerComponent.Instance.WaitFrameAsync();

                // 接收
                if (socket.Available > 0)
                {
                    int messageLength = socket.ReceiveFrom(recvCache, ref recvIPEndPoint);
                    if (messageLength != 9)
                    {
                        Log.Error($"router connect error1: {connectId} {messageLength} {localConn} {remoteConn} {routerAddress} {realAddress}");
                        continue;
                    }

                    byte flag = recvCache[0];
                    if (flag != KcpProtocalType.RouterReconnectACK && flag != KcpProtocalType.RouterACK)
                    {
                        Log.Error($"router connect error2: {connectId} {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);
                }
            }
        }
Example #2
0
        private static async ETTask CheckAsync(RouterCheckComponent self)
        {
            Session session    = self.GetParent <Session>();
            long    instanceId = self.InstanceId;

            while (true)
            {
                if (self.InstanceId != instanceId)
                {
                    return;
                }

                await TimerComponent.Instance.WaitAsync(1000);

                if (self.InstanceId != instanceId)
                {
                    return;
                }

                long time = TimeHelper.ClientFrameTime();

                if (time - session.LastRecvTime < 7 * 1000)
                {
                    continue;
                }

                try
                {
                    long     sessionId  = session.Id;
                    uint     localConn  = 0;
                    uint     remoteConn = 0;
                    KService service    = session.AService as KService;
                    KChannel kChannel   = service.Get(sessionId);
                    if (kChannel == null)
                    {
                        Log.Warning($"not found remoteConn: {sessionId}");
                        continue;
                    }

                    localConn  = kChannel.LocalConn;
                    remoteConn = kChannel.RemoteConn;

                    IPEndPoint realAddress = self.GetParent <Session>().RemoteAddress;
                    Log.Info($"get recvLocalConn start: {self.ClientScene().Id} {realAddress} {localConn} {remoteConn}");

                    (uint recvLocalConn, IPEndPoint routerAddress) = await RouterHelper.GetRouterAddress(self.ClientScene(), realAddress, localConn, remoteConn);

                    if (recvLocalConn == 0)
                    {
                        Log.Error($"get recvLocalConn fail: {self.ClientScene().Id} {routerAddress} {realAddress} {localConn} {remoteConn}");
                        continue;
                    }

                    Log.Info($"get recvLocalConn ok: {self.ClientScene().Id} {routerAddress} {realAddress} {recvLocalConn} {localConn} {remoteConn}");

                    session.LastRecvTime = TimeHelper.ClientNow();

                    ((KService)session.AService).ChangeAddress(sessionId, routerAddress);
                }
                catch (Exception e)
                {
                    Log.Error(e);
                }
            }
        }