I have a HttpListener
which is waiting for incoming requests. The curious thing is that when I send a request
with the HttpClient
or WebRequest
class, the reading/decoding of the stream
takes around 350ms, while sending the same request
with Insomnia
(https://insomnia.rest/) it only takes 500ticks!!
Can someone explain to me where is my fault?!
private readonly HttpClient _Client = new HttpClient();
private async void HttpClientMethod(string jsonContent)
{
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, _BaseUrl);
message.Content = new StringContent(jsonContent);
HttpResponseMessage result = await _Client.SendAsync(message);
string content = await result.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
private string WebRequestMethod(string jsonContent)
{
WebRequest request = WebRequest.Create(_BaseUrl);
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = jsonContent;
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
return responseFromServer;
}
private void ReadInputStream(HttpListenerRequest request)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
string text;
using (StreamReader reader = new StreamReader(request.InputStream, request.ContentEncoding))
{
text = reader.ReadToEnd();
}
stopwatch.Stop();
}
Just create a new Console App
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ApiTest
{
class Program
{
static readonly ApiHost _ApiHost = new ApiHost();
static readonly HttpClient _Client = new HttpClient();
static void Main(string[] args) => MainAsync(args).GetAwaiter().GetResult();
static async Task MainAsync(string[] args)
{
_ApiHost.Start();
Console.WriteLine("Host started");
Console.ReadKey();
string jsonContent ="{\"OperationName\":null,\"Query\":\"query {\\r\\n\\t hero{\\r\\n\\t\\t name,\\r\\n\\t\\t id\\r\\n\\t }\\r\\n\\t human(id: \\\"1\\\"){\\r\\n\\r\\n homePlanet,\\r\\n name\\r\\n\\r\\n }\\r\\n }\",\"Variables\":null}";
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, new Uri("http://localhost:5000/"));
message.Content = new StringContent(jsonContent);
HttpResponseMessage result = await _Client.SendAsync(message);
string content = await result.Content.ReadAsStringAsync();
Console.WriteLine(content);
Console.ReadKey();
}
}
}
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace ApiTest
{
public class ApiHost
{
public HttpListener Listener = new HttpListener();
private bool _Stop;
public void Start()
{
Listener.Prefixes.Add("http://+:5000/");
Listener.Start();
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(4, 4);
while (!_Stop)
{
semaphore.WaitOne();
Listener.GetContextAsync().ContinueWith(async (contextTask) =>
{
try
{
semaphore.Release();
HttpListenerContext context = await contextTask.ConfigureAwait(false);
Process(context);
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
});
}
});
}
private void Process(HttpListenerContext ctx)
{
try
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
string text;
using (StreamReader reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding))
{
text = reader.ReadToEnd();
}
stopwatch.Stop();
using (Stream output = ctx.Response.OutputStream)
{
using (StreamWriter writer = new StreamWriter(output) { AutoFlush = true })
{
writer.Write(text);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
Why do I have 360ms when using the internal library. When I use Insomnia
for example I don't have this delay!