// 向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); } } }
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); } } }