Example #1
0
        public async Task HandleAsync(object @event)
        {
            if (_clientInfoRepository.GetClientInfo() != null)
            {
                _clientInfoRepository.DeleteClientInfo();
            }

            _clientInfoRepository.AddClientInfo(JsonConvert.DeserializeObject <ClientInfo>(@event.ToString()));

            await _discordRestClient.PostMessage("764840399696822322", "Ready to serve");
        }
Example #2
0
        private async Task OnMessageReceive(string message)
        {
            var payload = JsonConvert.DeserializeObject <GatewayPayload>(message);

            if (payload.EventName is null)
            {
                _logger.LogInformation("[{0}]", payload.Opcode.ToString().ToUpperInvariant());
            }
            else
            {
                _logger.LogInformation("[{0} - {1}]", payload.Opcode.ToString().ToUpperInvariant(), payload.EventName);
            }

            SetSequenceNumber(payload.SequenceNumber);
            _lastMessageTime = Environment.TickCount;

            switch (payload.Opcode)
            {
            case GatewayOpCode.Hello:
            {
                SetCancellationToken();

                var heartbeatInterval = JsonConvert.DeserializeObject <HeartbeatEvent>(
                    payload.EventData.ToString()).HeartbeatInterval;

                _heartbeatTask = RunHeartbeat(heartbeatInterval);
            }
            break;

            case GatewayOpCode.Reconnect:
            {
                CloseHeartbeating();
                await CreateConnectionAsync(WebSocketCloseStatus.NormalClosure);
            }
            break;

            case GatewayOpCode.Heartbeat:
            {
                _logger.LogWarning("Server requested manual heartbeat!");

                var heartbeatEvent = new GatewayPayload
                {
                    Opcode    = GatewayOpCode.Heartbeat,
                    EventData = _sequenceNumber ?? null,
                };

                var heartbeatEventBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(heartbeatEvent));
                await _discordSocketClient.SendAsync(heartbeatEventBytes, true);
            }
            break;

            case GatewayOpCode.HeartbeatAck:
            {
                if (_heartbeatTimes.TryDequeue(out long time))
                {
                    int latency = (int)(Environment.TickCount - time);
                    int before  = _latency;
                    _latency = latency;

                    _logger.LogWarning("Latency: old - {0}ms | new - {1}ms", before, _latency);
                }
            }
            break;

            case GatewayOpCode.InvalidSession:
            {
                _logger.LogWarning("Cannot resume session!");

                CloseHeartbeating();
                if (bool.TryParse(payload.EventData.ToString(), out bool canBeResumed) && canBeResumed)
                {
                    await CreateConnectionAsync(WebSocketCloseStatus.NormalClosure);
                }
                else
                {
                    // Delete old session id
                    _clientInfoRepository.DeleteClientInfo();
                    SetSequenceNumber(0);
                    await Task.Delay(new Random().Next(1, 6) * 1000);
                    await CreateConnectionAsync(WebSocketCloseStatus.EndpointUnavailable);
                }
            }
            break;

            case GatewayOpCode.Dispatch:
            {
                await EventReceive.Invoke(payload);
            }
            break;

            default:
                _logger.LogWarning("Received unhandled event! - {0} {1} {2}", payload.Opcode.ToString().ToUpperInvariant(),
                                   payload.EventName ?? string.Empty, payload.EventData ?? string.Empty);
                break;
            }
        }