void KeepLocker(Locker <UdpClient2> locker) { PostEvictionCallbackRegistration cb = new PostEvictionCallbackRegistration(); cb.EvictionCallback = (key, value, reason, state) => { if (reason == EvictionReason.Expired)// { _logger?.LogInformation($"UDP server locker expired:{key.ToString()},{reason.ToString()}"); Locker <UdpClient2> locker = value as Locker <UdpClient2>; if ((DateTime.Now - locker.Owner.LastActive).TotalMilliseconds <= CLIENT_ACTIVE_TIMEOUT) { KeepLocker(locker); _logger?.LogInformation($"UDP locker cache readd:{key.ToString()}"); } else { locker.Destroy(); } } }; _clientLockers.Set(locker.Number, locker, TimeSpan.FromMilliseconds(CLIENT_ACTIVE_TIMEOUT), cb); }
/// <summary> /// /// </summary> /// <returns>usually null.</returns> public override async Task <UdpClient2> Accept()//TODO MaxNumClient limit. //TODO blocklist. { if (null == _listenerClient) { return(null); } try { #region receive packet FixedSizeBuffer buff = _bufferPool.Rent(); ArraySegment <byte> seg = new ArraySegment <byte>(buff.Memory, buff.Offset, buff.Memory.Length); //TODO cache IPEndPoint clientEndPoint = new IPEndPoint(_listenerClient.Client.LocalEndPoint.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, 0); var received = await _listenerClient.Client.ReceiveFromAsync(seg, SocketFlags.None, clientEndPoint);// _listenerClient.Client.LocalEndPoint); buff.SignificantLength = received.ReceivedBytes; #endregion //////var received = await _listenerClient.ReceiveAsync(); var locker = _clientLockers.Get(received.RemoteEndPoint); if (null != locker)// { #region delivery packet if ((DateTime.Now - locker.Owner.LastActive).TotalMilliseconds <= CLIENT_ACTIVE_TIMEOUT) { locker.PutPacket(buff); return(null); } else//inactive { DeleteLocker(received.RemoteEndPoint); buff.Pool.Return(buff);//drop packet. return(null); } #endregion } else { #region create client locker = new Locker <UdpClient2>(received.RemoteEndPoint as IPEndPoint); locker.PutPacket(buff); KeepLocker(locker); _logger?.LogInformation($"UdpServer New client:[{locker.Number.ToString()}]."); return(CreateClient(_listenerClient.Client, locker)); #endregion } } catch (SocketException se) { _logger?.LogError($"UdpServer ReceiveFromAsync error {se.SocketErrorCode}, {se.Message}."); return(null); } catch (Exception ex) { _logger?.LogError($"UdpServer ReceiveFromAsync error {ex.Message}."); return(null); } }