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,26 +15,53 @@ 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>>>();
try
{
var endpoint = new IPEndPoint( server.Address, server.QueryPort );
using ( var client = new UdpClient() ) internal static Task<Dictionary<string, string>> GetRules( ServerInfo server )
{ {
client.Client.SendTimeout = 3000; var endpoint = new IPEndPoint(server.Address, server.QueryPort);
client.Client.ReceiveTimeout = 3000;
client.Connect( endpoint );
return await GetRules( client ); lock (PendingQueries)
} {
} if (PendingQueries.TryGetValue(endpoint, out var pending))
catch ( System.Exception e ) return pending;
{
//Console.Error.WriteLine( e.Message ); var task = GetRulesImpl(endpoint, server)
return null; .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
{
using (var client = new UdpClient())
{
client.Client.SendTimeout = 3000;
client.Client.ReceiveTimeout = 3000;
client.Connect(endpoint);
return await GetRules(client);
}
}
catch (System.Exception e)
{
//Console.Error.WriteLine( e.Message );
return null;
}
} }
static async Task<Dictionary<string, string>> GetRules( UdpClient client ) static async Task<Dictionary<string, string>> GetRules( UdpClient client )