Example #1
0
 /// <summary>
 /// Disconnects this client from Discord. This method must be called when you are finished with this object.
 /// </summary>
 public void Disconnect()
 {
     _heartbeater.Dispose();
     _dispatcher.TearDown();
     _listener.Dispose();
     _heartbeater = null;
     _listener    = null;
     _dispatcher  = null;
     // TODO: Disconnect
 }
Example #2
0
 public GatewayHeartbeater(ResponseListener listener, SemaphoreSlim seqMutex, Func <long?> seqGetter, Func <bool, bool, Task> connect)
 {
     // TODO: Send heartbeat back when gateway requests a heartbeat (listen for GatewayOpCode.Heartbeat)
     _listener  = listener;
     _seqMutex  = seqMutex;
     _seqGetter = seqGetter;
     _aborts    = 0;
     _fire      = false;
     _ackMutex  = new SemaphoreSlim(1);
     _heardAck  = true;
     _connect   = connect;
 }
Example #3
0
        private async Task <Server[]> HandshakeAsync(bool reconnect, bool resumable, GatewaySocket socket, IRef <bool> loop)
        {
            DiscordDebug.WriteLine("Getting Hello data...");
            ReceiveGatewayData data = await socket.ReadAsync();

            DiscordDebug.WriteLine("Got Hello data.");
            if (reconnect)
            {
                _listener.UpdateSocket(socket);
            }
            else
            {
                DiscordDebug.WriteLine("Initializing response listener and heartbeater...");
                _listener    = new ResponseListener(socket);
                _heartbeater = new GatewayHeartbeater(_listener, _seqMutex, () => _lastSequence, ConnectAsync);
                DiscordDebug.WriteLine("Response listener and heartbeater initialized.");
            }
            // Need to handle cases where heartbeat timer elapses, thus the event/semaphore model
            DiscordDebug.WriteLine("Waiting for initial heartbeat ack...");
            var  signal  = new Semaphore(0, 1);
            bool success = false;

            void EvtListener(object sender, bool e)
            {
                success = e;
                signal.Release();
            }

            _heartbeater.Started += EvtListener;
            _heartbeater.Start(data, reconnect);
            signal.WaitOne();
            _heartbeater.Started -= EvtListener;
            if (success)
            {
                DiscordDebug.WriteLine("Heartbeat ack heard.");
                return(await IdentAsync(reconnect, resumable));

                // ReSharper disable once RedundantIfElseBlock
            }
            else
            {
                DiscordDebug.WriteLine("Heartbeat ack not heard, trying again...");
                // Reconnect immediately
                await _heartbeater.AbortAsync();

                _heartbeater.Dispose();
                _listener.Dispose();
                loop.Value = true;
                return(null);
            }
        }