Lobby architecture in the lobby

I created an online poker system using WCF net.tcp and WPF for the interface. It works great, but I feel that there are some things that I can improve when I convert the front end to Silverlight.

One of the questions I have for fellow architects is how to update the gaming lobby? The conduct of a poker game is constantly updated with statistics, for example, the number of players, hands per hour and the percentage of the flop.

Since there can be hundreds of games at any given time, I’m not sure that returning the entire list of games every 5 seconds (polling) is optimal. I thought to use a delta query, since many games will not have status updates (for example, no player on the table).

I was thinking about using update time, so every time a client (which can be hundreds or even thousands!) Polls, only those records that are updated for 5, 10 or more seconds are returned.

The game lobby client will, of course, be responsible for reconciling the new data, but I think this could ease some of the load on the game servers.

Any ideas?

+4
source share
2 answers
<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; } } } 
0
source

You can choose the approach in which clients register on the server for cyclical updates. Thus, the server will provide a service contract with a callback contract (duplex contract), which the client will have to implement. See here for more details.

On the other hand, it can be difficult to use a two-way contract from a Silverlight client (I'm not sure if this is possible at all), so polling with an update interval is a legal approach. The server should send the current timestamp along with the response data of the polling cycle, which the client sent with its next request to indicate when updated data is requested. Avoid comparing client and server time.

+2
source

Source: https://habr.com/ru/post/1390298/


All Articles