diff --git a/Balancer/.nuget/NuGet.Config b/Balancer/.nuget/NuGet.Config new file mode 100644 index 0000000..67f8ea0 --- /dev/null +++ b/Balancer/.nuget/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Balancer/.nuget/NuGet.exe b/Balancer/.nuget/NuGet.exe new file mode 100644 index 0000000..8dd7e45 Binary files /dev/null and b/Balancer/.nuget/NuGet.exe differ diff --git a/Balancer/.nuget/NuGet.targets b/Balancer/.nuget/NuGet.targets new file mode 100644 index 0000000..3f8c37b --- /dev/null +++ b/Balancer/.nuget/NuGet.targets @@ -0,0 +1,144 @@ + + + + $(MSBuildProjectDirectory)\..\ + + + false + + + false + + + true + + + false + + + + + + + + + + + $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) + + + + + $(SolutionDir).nuget + + + + $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config + $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config + + + + $(MSBuildProjectDirectory)\packages.config + $(PackagesProjectConfig) + + + + + $(NuGetToolsPath)\NuGet.exe + @(PackageSource) + + "$(NuGetExePath)" + mono --runtime=v4.0.30319 "$(NuGetExePath)" + + $(TargetDir.Trim('\\')) + + -RequireConsent + -NonInteractive + + "$(SolutionDir) " + "$(SolutionDir)" + + + $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) + $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols + + + + RestorePackages; + $(BuildDependsOn); + + + + + $(BuildDependsOn); + BuildPackage; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ProxyToHashServer/App.config b/Balancer/App.config similarity index 100% rename from ProxyToHashServer/App.config rename to Balancer/App.config diff --git a/Balancer/Listener.cs b/Balancer/Listener.cs new file mode 100644 index 0000000..8a8faab --- /dev/null +++ b/Balancer/Listener.cs @@ -0,0 +1,54 @@ +using System; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using log4net; + +namespace ProxyToHashServer +{ + public class Listener + { + private HttpListener listener; + + public Listener(int port, string suffix, Func callbackAsync) + { + ThreadPool.SetMinThreads(8, 8); + CallbackAsync = callbackAsync; + listener = new HttpListener(); + listener.Prefixes.Add(string.Format("http://+:{0}{1}/", port, suffix != null ? "/" + suffix.TrimStart('/') : "")); + } + + public void Start() + { + listener.Start(); + StartListen(); + } + + public async void StartListen() + { + while (true) + { + var context = await listener.GetContextAsync(); + + Task.Run( + async () => + { + var ctx = context; + try + { + await CallbackAsync(ctx); + } + finally + { + ctx.Response.Close(); + } + } + ); + } + } + + private Func CallbackAsync { get; set; } + + private static readonly ILog log = LogManager.GetLogger(typeof(Program)); + } +} diff --git a/ProxyToHashServer/Program.cs b/Balancer/Program.cs similarity index 54% rename from ProxyToHashServer/Program.cs rename to Balancer/Program.cs index 1f3585c..54ec0ef 100644 --- a/ProxyToHashServer/Program.cs +++ b/Balancer/Program.cs @@ -1,10 +1,10 @@ -using HashServer; -using log4net; +using log4net; using log4net.Config; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Compression; using System.Linq; using System.Net; using System.Text; @@ -17,17 +17,15 @@ static class Program { private static readonly Random rand = new Random(); private const int defaultPort = 20000; + private const int timeout = 1500; private static readonly ILog log = LogManager.GetLogger(typeof(Program)); private static readonly string[] hashServers = //пока это будет тут, потом перенесу в файл, если нужно будет. new string[] { - "127.0.0.1:21612", - "127.0.0.1:21613", - "127.0.0.1:21614", - "127.0.0.1:21615", - "127.0.0.1:21616", + "127.0.0.1:22722", + "127.0.0.1:22723", }; static void Main(string[] args) @@ -59,21 +57,54 @@ private static async Task OnContextAsync(HttpListenerContext context) log.InfoFormat("{0}: received {1} from {2}", requestId, query, remoteEndPoint); context.Request.InputStream.Close(); MemoryStream ms = null; + var usableServers = hashServers.ToList(); + string server = null; while (ms == null) { try { - ms = await DownloadWebPageAsync(hashServers[rand.Next(hashServers.Length)], query); + if (usableServers.Count == 0) + { + log.InfoFormat("All servers unavailible"); + context.Response.StatusCode = 500; + context.Response.Close(); + return; + } + var tasks = new Task[2]; + server = usableServers[rand.Next(usableServers.Count)]; + tasks[0] = Task.Run(async () => + { + await Task.Delay(timeout); + return (MemoryStream)null; + }); + tasks[1] = DownloadWebPageAsync(server, query); + var task = await Task.WhenAny(tasks); + ms = task.Result; + if (ms == null) + { + usableServers.Remove(server); + log.InfoFormat("server request timed out"); + } } - catch (Exception) + catch (Exception e) { + usableServers.Remove(server); log.InfoFormat("Server down"); + log.InfoFormat(((AggregateException)e).InnerExceptions[0].GetType().ToString()); } } - var encryptedBytes = ms.ToArray(); - - await context.Response.OutputStream.WriteAsync(encryptedBytes, 0, encryptedBytes.Length); - context.Response.OutputStream.Close(); + var encryptedBytes = ms.ToArray(); + var encodings = context.Request.Headers.GetValues("Accept-Encoding"); + var stream = context.Response.OutputStream; + Console.WriteLine(encodings.Count()); + if (encodings != null && encodings.Contains("deflate")) + { + context.Response.AddHeader("Content-Encoding", "deflate"); + stream = new DeflateStream(stream, CompressionLevel.Optimal); + log.InfoFormat("data encoded"); + } + await stream.WriteAsync(encryptedBytes, 0, encryptedBytes.Length); + stream.Close(); log.InfoFormat("{0}: {1} sent back to {2}", requestId, Encoding.UTF8.GetString(encryptedBytes), remoteEndPoint); } @@ -87,6 +118,7 @@ public static async Task DownloadWebPageAsync(string ipAndPortOfSe { await stream.CopyToAsync(ms); Console.WriteLine("Got {0} bytes in {1} ms", ms.Position, sw.ElapsedMilliseconds); + log.InfoFormat("Got {0} bytes in {1} ms", ms.Position, sw.ElapsedMilliseconds); } return ms; } diff --git a/ProxyToHashServer/Properties/AssemblyInfo.cs b/Balancer/Properties/AssemblyInfo.cs similarity index 100% rename from ProxyToHashServer/Properties/AssemblyInfo.cs rename to Balancer/Properties/AssemblyInfo.cs diff --git a/ProxyToHashServer/ProxyToHashServer.csproj b/Balancer/ProxyToHashServer.csproj similarity index 93% rename from ProxyToHashServer/ProxyToHashServer.csproj rename to Balancer/ProxyToHashServer.csproj index 7f1d274..8d480db 100644 --- a/ProxyToHashServer/ProxyToHashServer.csproj +++ b/Balancer/ProxyToHashServer.csproj @@ -46,6 +46,7 @@ + @@ -55,12 +56,6 @@ - - - {26e99604-5e67-4f52-8c0e-63879569c3b0} - HashServer - -