public int IncreasePlayCount(QueueItem item)
        {
            QueueItem changed = _items.AddOrUpdate(item.TweetId, item, Update);

            ItemPlayed?.Invoke(this, new ItemPlayedEventArgs(changed));

            return(changed.Played);

            QueueItem Update(long key, QueueItem existing)
            {
                existing.Played++;
                return(existing);
            }
        }
        public async Task RunAsync(CancellationToken stoppingToken)
        {
            var buffer = new ArraySegment <byte>(new byte[2048]);
            await _webSocket.ConnectAsync(new Uri("ws://localhost:50080/connect"), CancellationToken.None);

            while (!stoppingToken.IsCancellationRequested)
            {
                WebSocketReceiveResult received;
                using MemoryStream data = new MemoryStream();

                do
                {
                    received = await _webSocket.ReceiveAsync(buffer, stoppingToken);

                    Console.WriteLine("Received {0} b ({1})", received.Count, received.EndOfMessage);
                    await data.WriteAsync(buffer.Slice(0, received.Count));
                } while (!received.EndOfMessage);

                var type = GetType(data);

                switch (type)
                {
                case NotificationType.UserChanged:
                {
                    var userNotification = UserChangedNotification.Parser.ParseFrom(data);

                    UsersChanged?.Invoke(this, new UserChangedEventArgs(userNotification));
                    break;
                }

                case NotificationType.QueueChanged:
                {
                    var notification = QueueChangedNotification.Parser.ParseFrom(data);

                    QueueChanged?.Invoke(this, new ItemsChangedEventArgs(notification));
                    break;
                }

                case NotificationType.ItemsChanged:
                {
                    var notification = QueueChangedNotification.Parser.ParseFrom(data);

                    ItemsChanged?.Invoke(this, new ItemsChangedEventArgs(notification));
                    break;
                }

                case NotificationType.ItemPlayed:
                {
                    var notification = ItemPlayedNotification.Parser.ParseFrom(data);

                    ItemPlayed?.Invoke(this, new ItemPlayedEventArgs(notification));
                    break;
                }

                default:
                    Console.WriteLine("Unknown Type \"{0}\"", type);
                    break;
                }
            }

            await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye", CancellationToken.None);

            NotificationType GetType(MemoryStream data)
            {
                try
                {
                    data.Seek(0, SeekOrigin.Begin);
                    var item = NotificationItem.Parser.ParseFrom(data);
                    Console.WriteLine("Parsed `NotificationItem`: {0}", item != null);

                    data.Seek(0, SeekOrigin.Begin);

                    return(item.Type);
                }
                catch (Exception e)
                {
                    return(NotificationType.None);
                }
            }
        }