Limit SourceServerQuery to one concurrent request per endpoint

This commit is contained in:
Rohan Singh 2019-12-07 08:41:06 -05:00
parent 2e6db5fe37
commit 710c6a0ce7
8 changed files with 45 additions and 18 deletions

View File

@ -15,22 +15,49 @@ internal static class SourceServerQuery
// private static readonly byte A2S_PLAYER = 0x55; // private static readonly byte A2S_PLAYER = 0x55;
private static readonly byte A2S_RULES = 0x56; private static readonly byte A2S_RULES = 0x56;
internal static async Task<Dictionary<string, string>> GetRules( ServerInfo server ) private static readonly Dictionary<IPEndPoint, Task<Dictionary<string, string>>> PendingQueries =
new Dictionary<IPEndPoint, Task<Dictionary<string, string>>>();
internal static Task<Dictionary<string, string>> GetRules( ServerInfo server )
{
var endpoint = new IPEndPoint(server.Address, server.QueryPort);
lock (PendingQueries)
{
if (PendingQueries.TryGetValue(endpoint, out var pending))
return pending;
var task = GetRulesImpl(endpoint, server)
.ContinueWith(t =>
{
lock (PendingQueries)
{
PendingQueries.Remove(endpoint);
}
return t;
})
.Unwrap();
PendingQueries.Add(endpoint, task);
return task;
}
}
private static async Task<Dictionary<string, string>> GetRulesImpl( IPEndPoint endpoint, ServerInfo server )
{ {
try try
{ {
var endpoint = new IPEndPoint( server.Address, server.QueryPort ); using (var client = new UdpClient())
using ( var client = new UdpClient() )
{ {
client.Client.SendTimeout = 3000; client.Client.SendTimeout = 3000;
client.Client.ReceiveTimeout = 3000; client.Client.ReceiveTimeout = 3000;
client.Connect( endpoint ); client.Connect(endpoint);
return await GetRules( client ); return await GetRules(client);
} }
} }
catch ( System.Exception e ) catch (System.Exception e)
{ {
//Console.Error.WriteLine( e.Message ); //Console.Error.WriteLine( e.Message );
return null; return null;