Domanda

Ho creato un sistema di poker online utilizzando WCF net.tcp e WPF per il front-end. E le grandi opere, ma mi sento ci sono alcune cose che posso migliorare, quando converto il front-end per Silverlight.

Una delle domande che ho per colleghi architetti è come dovrebbe la lobby di gioco possibile aggiornare? Una lobby di gioco di poker è continuamente aggiornato con le statistiche come il numero di giocatori, mani per ora, e la percentuale di flop.

Dato che ci potrebbero essere centinaia di giochi in corso in un dato momento, non sono così sicuro che il ritorno l'intero elenco di giochi ogni 5 secondi (polling) è ottimale. Stavo pensando di utilizzare una query delta dal momento che molti giochi non avranno aggiornamenti di stato (es .: nessun giocatore sul tavolo).

Stavo pensando di utilizzare un tempo di aggiornamento in modo che ogni volta che un cliente (che può essere centinaia o migliaia addirittura!) Sondaggio, solo i record aggiornati entro diciamo 5, 10, o più secondi vengono restituiti.

Il client del gioco hall sarà ovviamente il compito di conciliare i nuovi dati, ma penso che questo potrebbe contribuire ad alleviare alcuni degli oneri sui server di gioco.

Tutte le idee?

È stato utile?

Soluzione 2

<Window x:Class="TestListUpdate.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ListView Name="listView1">
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="140" Header="Name" DisplayMemberBinding="{Binding Value.Name}" />
                    <GridViewColumn Width="140" Header="Creator" DisplayMemberBinding="{Binding Value.Creator}" />
                    <GridViewColumn Width="140" Header="Publisher" DisplayMemberBinding="{Binding Value.Publisher}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>


namespace TestListUpdate
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        Dictionary<int, GameData> _gameData = null;

        // This is a test, real data will be retrieved via a web service
        List<GameData> _updates = null;

        public Window1()
        {
            InitializeComponent();

            // This is the original data bound to the ListView control
            this._gameData = new Dictionary<int, GameData>();
            this._gameData.Add(1, new GameData { Id = 1, Creator = "ABC", Name = "One", Publisher = "123" });
            this._gameData.Add(2, new GameData { Id = 2, Creator = "DEF", Name = "Two", Publisher = "456" });
            this._gameData.Add(3, new GameData { Id = 3, Creator = "GHI", Name = "Three", Publisher = "789" });
            this._gameData.Add(4, new GameData { Id = 4, Creator = "JKL", Name = "Four", Publisher = "abc" });
            this._gameData.Add(5, new GameData { Id = 5, Creator = "MNO", Name = "Five", Publisher = "def" });

            // This is test data, some Ids are duplicates of the original data above
            // other items represent new items
            this._updates = new List<GameData>();
            this._updates.Add(new GameData { Id = 2, Creator = "DDD", Name = "Two", Publisher = "123" });
            this._updates.Add(new GameData { Id = 3, Creator = "TTT", Name = "Three", Publisher = "456" });
            this._updates.Add(new GameData { Id = 5, Creator = "FFF", Name = "Five", Publisher = "789" });
            this._updates.Add(new GameData { Id = 6, Creator = "XXX", Name = "Six", Publisher = "abc" });
            this._updates.Add(new GameData { Id = 7, Creator = "VVV", Name = "Seven", Publisher = "def" });

            System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 5);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            // Get a list of Ids from the new data
            var ids = (from l in this._updates
                       select l.Id);

            // Get a list of items that have matching Ids,
            // this data will be updated
            var updates = (from g in this._gameData
                           where ids.Contains(g.Value.Id)
                           select g);

            // Update the current items
            for (int i = 0; i < updates.Count(); ++i)
            {
                KeyValuePair<int, GameData> kvp = updates.ElementAt(i);
                kvp.Value.Publisher = DateTime.Now.ToLongTimeString();
            }

            // This represents new items to add
            this._gameData = this._gameData.Concat(
                    (from n in this._updates
                     where !this._gameData.ContainsKey(n.Id)
                     select n).ToDictionary(a => a.Id, a => a)
                 ).ToDictionary(q => q.Key, q => q.Value);

            // This is a simple trick to rebind the ListView control
            this.listView1.ItemsSource = null;
            this.listView1.ItemsSource = GameList;
        }

        // Databinding property
        public Dictionary<int, GameData> GameList
        {
            get { return this._gameData; }
        }
    }

    // Data class
    public class GameData
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Creator { get; set; }
        public string Publisher { get; set; }
    }
}

Altri suggerimenti

Si potrebbe scegliere un approccio in cui registrare i client al server per gli aggiornamenti ciclici. Il server quindi fornire un contratto di servizio con un contratto di richiamata (un contratto duplex) che il cliente avrebbe dovuto attuare. Vedere qui per i dettagli.

D'altra parte potrebbe essere difficile usare un contratto duplex da un client di Silverlight (non sono sicuro se è possibile a tutti), così polling con un intervallo di tempo di aggiornamento è un approccio giuridico. Il server deve inviare un timestamp corrente insieme ai dati di risposta di un ciclo di polling, che il cliente avrebbe rispediti con la sua prossima richiesta di indicare da quando è richiesta dati aggiornati. Evitare di confrontare i tempi di client e server.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top