Exemple #1
0
        /// <summary>
        ///     Processes the payload and invokes the <see cref="LavalinkSocket.PayloadReceived"/>
        ///     event asynchronously. (Can be override for event catching)
        /// </summary>
        /// <param name="eventArgs">the event arguments</param>
        /// <returns>a task that represents the asynchronous operation</returns>
        protected override async Task OnPayloadReceived(PayloadReceivedEventArgs eventArgs)
        {
            var payload = eventArgs.Payload;

            // received an event
            if (payload is EventPayload eventPayload)
            {
                await OnEventReceived(eventPayload);
            }

            // received a payload for a player
            if (payload is IPlayerPayload playerPayload)
            {
                await OnPlayerPayloadReceived(playerPayload);
            }

            // statistics update received
            if (payload is StatsUpdatePayload statsUpdate)
            {
                Statistics = new NodeStatistics(statsUpdate.Players, statsUpdate.PlayingPlayers,
                                                statsUpdate.Uptime, statsUpdate.Memory, statsUpdate.Processor, statsUpdate.FrameStatistics);

                await OnStatisticsUpdateAsync(new NodeStatisticsUpdateEventArgs(Statistics));
            }

            await base.OnPayloadReceived(eventArgs);
        }
Exemple #2
0
        private void OnReceived(object sender, PayloadReceivedEventArgs args)
        {
            // TODO KZ: handle missing packets
            var packet = (Packet)args.Payload;

            if (packet.Total == 1)
            {
                Received?.Invoke(this, new MessageReceivedEventArgs(packet.Sender, packet.Total, packet.Message, args.Received, args.Received));
                return;
            }

            var key             = new MessageKey(packet.Sender, packet.Sequence, packet.Total);
            var receivedContext = _receivedContexts.GetValueOrAdd(key, _ => new ReceivedContext(packet.Total));

            receivedContext.Chunks.Add(packet.Message);

            if (receivedContext.Chunks.Count == 1)
            {
                receivedContext.FirstSent = args.Received;

                return;
            }

            if (receivedContext.Chunks.Count != packet.Total)
            {
                return;
            }

            Received?.Invoke(this, new MessageReceivedEventArgs(packet.Sender, packet.Total, receivedContext.Chunks.Concat(), receivedContext.FirstSent, args.Received));
            _receivedContexts.Remove(key);
        }
        /// <summary>
        ///     Processes an incoming payload asynchronously.
        /// </summary>
        /// <remarks>
        ///     This method should not be called manually. It is called in the connection life cycle,
        ///     see: <see cref="RunLifeCycleAsync"/>.
        /// </remarks>
        /// <returns>a task that represents the asynchronous operation</returns>
        /// <exception cref="ObjectDisposedException">thrown if the instance is disposed</exception>
        private async Task ProcessNextPayload()
        {
            EnsureNotDisposed();

            WebSocketReceiveResult result;

            try
            {
                result = await _webSocket !.ReceiveAsync(new ArraySegment <byte>(_receiveBuffer, 0, _receiveBuffer.Length), _cancellationTokenSource !.Token);
            }
            catch (WebSocketException ex)
            {
                if (_cancellationTokenSource !.IsCancellationRequested)
                {
                    return;
                }

                Logger?.Log(ex, "Lavalink Node disconnected (without handshake, maybe connection loss or server crash)");
                await OnDisconnectedAsync(new DisconnectedEventArgs(_webSocketUri, WebSocketCloseStatus.Empty, string.Empty, true));

                _webSocket?.Dispose();
                _webSocket = null;
                return;
            }

            // check if the web socket received a close frame
            if (result.MessageType == WebSocketMessageType.Close)
            {
                Logger?.Log(this, string.Format("Lavalink Node disconnected: {0}, {1}.", result.CloseStatus.GetValueOrDefault(), result.CloseStatusDescription), LogLevel.Warning);
                await OnDisconnectedAsync(new DisconnectedEventArgs(_webSocketUri, result.CloseStatus.GetValueOrDefault(), result.CloseStatusDescription, true));

                _webSocket.Dispose();
                _webSocket = null;
                return;
            }

            var content = Encoding.UTF8.GetString(_receiveBuffer, 0, result.Count);

            if (!result.EndOfMessage)
            {
                // the server sent a message frame that is incomplete
                _overflowBuffer.Append(content);
                return;
            }

            // check if old data exists
            if (result.EndOfMessage && _overflowBuffer.Length > 0)
            {
                _overflowBuffer.Append(content);
                content = _overflowBuffer.ToString();
                _overflowBuffer.Clear();
            }

            if (_ioDebug)
            {
                Logger?.Log(this, string.Format("Received payload: `{0}` from: {1}.", content, _webSocketUri), LogLevel.Trace);
            }

            // process data
            try
            {
                var payload   = PayloadConverter.ReadPayload(content);
                var eventArgs = new PayloadReceivedEventArgs(payload, content);
                await OnPayloadReceived(eventArgs);
            }
            catch (Exception ex)
            {
                Logger?.Log(this, string.Format("Received bad payload: {0}.", content), LogLevel.Warning, ex);
                await CloseAsync(WebSocketCloseStatus.InvalidPayloadData);
            }
        }
 /// <summary>
 ///     Invokes the <see cref="PayloadReceived"/> event asynchronously. (Can be override for
 ///     event catching)
 /// </summary>
 /// <param name="eventArgs">the event arguments for the event</param>
 /// <returns>a task that represents the asynchronous operation</returns>
 protected virtual Task OnPayloadReceived(PayloadReceivedEventArgs eventArgs)
 => PayloadReceived.InvokeAsync(this, eventArgs);
 public static void PayloadReceivedConsoleHandler(object sender, PayloadReceivedEventArgs e)
 {
     Console.WriteLine(new string(Encoding.UTF8.GetChars(e.Payload)));
 }