public static bool SendToClient(this RouterServiceComponent self, ulong remotelocalConn, int messageLength, byte[] cache) { if (self.clientsAddress.TryGetValue(remotelocalConn, out var iPEndPointEntity)) { self.socket.SendTo(cache, 0, messageLength, SocketFlags.None, iPEndPointEntity.ClientEndPoint); return(true); } else { return(false); } }
/// <summary> /// 获取ack或者切换路由成功时,移除连接信息.加入完整的路由信息 /// </summary> /// <param name="remoteConn"></param> /// <param name="localConn"></param> /// <returns></returns> public static bool GetACK(this RouterServiceComponent self, uint remoteConn, uint localConn) { Log.Debug($"GetACK:{localConn} {remoteConn}"); if (self.waitConnectChannels.TryGetValue(remoteConn, out var routerIPEndPoint)) { ulong remotelocal = ((ulong)remoteConn << 32) | localConn; self.clientsAddress[remotelocal] = routerIPEndPoint; self.waitConnectChannels.Remove(remoteConn); return(true); } return(false); }
public static void Update(this RouterServiceComponent self) { self.Recv(); var nowtime = TimeHelper.ClientNowSeconds(); if (self.CurrTimeSecond != nowtime) { self.CurrTimeSecond = nowtime; if (self.CurrTimeSecond % 3 == 0) { self.RemoveConnectTimeoutIds(); } } }
public static void Awake(this RouterServiceComponent self, IPEndPoint ipEndPoint) { self.StartTime = TimeHelper.ClientNow(); self.CurrTimeSecond = TimeHelper.ClientNowSeconds(); self.socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { self.socket.SendBufferSize = Kcp.OneM * 64; self.socket.ReceiveBufferSize = Kcp.OneM * 64; } self.socket.Bind(ipEndPoint); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { const uint IOC_IN = 0x80000000; const uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; self.socket.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null); } }
private static void RemoveConnectTimeoutIds(this RouterServiceComponent self) { self.waitRemoveAddress.Clear(); foreach (var clientaddress in self.clientsAddress.Keys) { if (self.TimeNow > self.clientsAddress[clientaddress].MsgTime + 30000) { self.waitRemoveAddress.Add(clientaddress); } } foreach (var clientkey in self.waitRemoveAddress) { self.clientsAddress.Remove(clientkey); } if (self.clientsAddress.Count > 1000) { Log.Debug("clientsAddress.Count要报警了!:" + self.clientsAddress.Count); } //下面清理半连接 self.waitRemoveConnectChannels.Clear(); foreach (var channel in self.waitConnectChannels.Keys) { if (self.TimeNow > self.waitConnectChannels[channel].MsgTime + 10000) { self.waitRemoveConnectChannels.Add(channel); } } foreach (var channelkey in self.waitRemoveConnectChannels) { self.waitConnectChannels.Remove(channelkey); } if (self.waitConnectChannels.Count > 1000) { Log.Debug("waitConnectChannels.Count要报警了!:" + self.waitConnectChannels.Count); } }
private static void Recv(this RouterServiceComponent self) { if (self.socket == null) { return; } while (self.socket != null && self.socket.Available > 0) { int messageLength = self.socket.ReceiveFrom(self.cache, ref self.ipEndPoint); // 长度小于1,不是正常的消息 if (messageLength < 1) { continue; } // accept byte flag = self.cache[0]; // conn从100开始,如果为1,2,3则是特殊包 uint remoteConn = 0; uint localConn = 0; ulong remotelocalConn = 0; try { switch (flag) { case KcpProtocalType.RouterSYN: remoteConn = BitConverter.ToUInt32(self.cache, 1); int gateid = BitConverter.ToInt32(self.cache, 5); if (StartSceneConfigCategory.Instance.Contain(gateid)) { var conf = StartSceneConfigCategory.Instance.Get(gateid); if (conf.SceneType == "Gate") { if (self.waitConnectChannels.TryGetValue(remoteConn, out var ipendpoint)) { //如果是自己重复发.就再返回,否则直接抛弃 if (ipendpoint.ClientEndPoint.ToString() == self.ipEndPoint.ToString()) { byte[] newbuffer = self.cache; newbuffer.WriteTo(0, KcpProtocalType.RouterACK); self.socket.SendTo(newbuffer, 0, 1, SocketFlags.None, self.ipEndPoint); Log.Debug("RouterSYN repeated:" + self.ipEndPoint.ToString()); } break; } //这是第一次添加 else { var inneraddress = conf.InnerIPOutPort; self.waitConnectChannels[remoteConn] = new RouterIPEndPoint(self.CloneAddress(), inneraddress, self.TimeNow); byte[] newbuffer = self.cache; newbuffer.WriteTo(0, KcpProtocalType.RouterACK); self.socket.SendTo(newbuffer, 0, 1, SocketFlags.None, self.ipEndPoint); Log.Debug("RouterSYN 成功:" + self.ipEndPoint.ToString()); break; } } } else { Log.Debug("Router SYN error:not found gate:" + gateid.ToString()); break; } break; case KcpProtocalType.SYN: // accept case KcpProtocalType.RouterReconnect: if (messageLength < 9) { break; } remoteConn = BitConverter.ToUInt32(self.cache, 1); if (self.waitConnectChannels.TryGetValue(remoteConn, out var routerIPEnd)) { //syn的时候更新客户端地址.有可能是不同的socket发来的 Log.Debug("SYN 之前地址:" + routerIPEnd.ClientEndPoint.ToString()); routerIPEnd.ClientEndPoint = self.CloneAddress(); self.Domain.GetComponent <RouterServiceInnerComponent>().SendToGate(self.cache, 9, routerIPEnd.TargetEndPoint); Log.Debug("SYN 地址变更成功:" + self.ipEndPoint.ToString()); } break; case KcpProtocalType.MSG: if (messageLength < 9) { break; } remoteConn = BitConverter.ToUInt32(self.cache, 1); localConn = BitConverter.ToUInt32(self.cache, 5); remotelocalConn = ((ulong)remoteConn << 32) | localConn; if (self.clientsAddress.TryGetValue(remotelocalConn, out var realTargetAddress)) { self.Domain.GetComponent <RouterServiceInnerComponent>().SendToGate(self.cache, messageLength, realTargetAddress.TargetEndPoint); realTargetAddress.MsgTime = self.TimeNow; } else { Log.Debug("Router MSG error:not found gateaddress:" + self.ipEndPoint.ToString()); break; } break; case KcpProtocalType.FIN: // 断开 if (messageLength < 9) { break; } remoteConn = BitConverter.ToUInt32(self.cache, 1); localConn = BitConverter.ToUInt32(self.cache, 5); remotelocalConn = ((ulong)remoteConn << 32) | localConn; if (self.clientsAddress.TryGetValue(remotelocalConn, out var finTargetAddress)) { self.Domain.GetComponent <RouterServiceInnerComponent>().SendToGate(self.cache, messageLength, finTargetAddress.TargetEndPoint); self.RemoveClientAddress(remotelocalConn); } else { Log.Debug("Router MSG FIN:not found gateaddress:" + self.ipEndPoint.ToString()); break; } break; } } catch (Exception e) { Log.Error($"RouterService error: {flag} {remoteConn} {localConn}\n{e}"); } } }
private static IPEndPoint CloneAddress(this RouterServiceComponent self) { IPEndPoint ip = (IPEndPoint)self.ipEndPoint; return(new IPEndPoint(ip.Address, ip.Port)); }
public static void Destroy(this RouterServiceComponent self) { self.socket.Close(); self.socket = null; }
public static void RemoveClientAddress(this RouterServiceComponent self, ulong remotelocalConn) { self.clientsAddress.Remove(remotelocalConn); }