private async void RttRoutine()
        {
            while (Running && !RttToken.IsCancellationRequested)
            {
                try {
                    await Task.Delay(RttInterval, RttToken.Token);
                } catch (Exception) { }

                if (!RttToken.IsCancellationRequested)
                {
                    foreach (var keypair in Users)
                    {
                        WebSocketUser user = keypair.Value;

                        if (user.RTT.Sending)
                        {
                            user.RTT.Last = RttInterval;

                            if (user.RTT.Max < RttInterval)
                            {
                                user.RTT.Max = RttInterval;
                                OnRTT?.Invoke(this, new RttEventArgs(user));
                            }
                        }

                        user.RTT.Sending = true;
                        user.RTT.Sent    = DateTime.UtcNow;

                        await user.Writer.WriteCustomPing();
                    }
                }
            }
        }
        private void OnPongReceived(WebSocketUser user)
        {
            if (user.RTT.Sending)
            {
                user.RTT.Sending = false;

                var span = DateTime.UtcNow - user.RTT.Sent;
                var ms   = user.RTT.Last = span.TotalMilliseconds;

                if (ms < user.RTT.Min || user.RTT.Min == -1)
                {
                    user.RTT.Min = ms;
                }

                if (ms > user.RTT.Max)
                {
                    user.RTT.Max = ms;
                }

                OnRTT?.Invoke(this, new RttEventArgs(user));

                //Logger.DebugWrite("INFO", $"RTT Last {user.RTT.Last} / {user.RTT.Min} / {user.RTT.Max}");
            }
        }