C
C#2y ago
marsastro

❔ ✅ HttpListener only receives context once

Hey, I've set up a class that listens for traffic on localhost coming from a different app. The class looks like this:
public class FluxApiService
{
private HueApiService _hueApiService;
private HttpListener _listener;
private string _url = "http://localhost:8000/";

public FluxApiService(HueApiService hueApiService)
{
_listener = new HttpListener();
_listener.Prefixes.Add(_url);
_hueApiService = hueApiService;
}

public void Start()
{
Task.Run(async () => { await HandleIncomingConnections(); });
}

private async Task HandleIncomingConnections()
{
_listener.Start();

while (true)
{
try
{
HttpListenerContext ctx = await _listener.GetContextAsync();

HttpListenerRequest req = ctx.Request;

if (req.Url == null) continue;

var colorTemp = HttpUtility.ParseQueryString(req.Url.Query).Get("ct");
var brightness = HttpUtility.ParseQueryString(req.Url.Query).Get("bri");

if (colorTemp == null || brightness == null) continue;

await _hueApiService.UpdateScenes(int.Parse(colorTemp), Math.Clamp(float.Parse(brightness) * 100f, 0f, 100f));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
_listener.Stop();
break;
}
}
}
}
public class FluxApiService
{
private HueApiService _hueApiService;
private HttpListener _listener;
private string _url = "http://localhost:8000/";

public FluxApiService(HueApiService hueApiService)
{
_listener = new HttpListener();
_listener.Prefixes.Add(_url);
_hueApiService = hueApiService;
}

public void Start()
{
Task.Run(async () => { await HandleIncomingConnections(); });
}

private async Task HandleIncomingConnections()
{
_listener.Start();

while (true)
{
try
{
HttpListenerContext ctx = await _listener.GetContextAsync();

HttpListenerRequest req = ctx.Request;

if (req.Url == null) continue;

var colorTemp = HttpUtility.ParseQueryString(req.Url.Query).Get("ct");
var brightness = HttpUtility.ParseQueryString(req.Url.Query).Get("bri");

if (colorTemp == null || brightness == null) continue;

await _hueApiService.UpdateScenes(int.Parse(colorTemp), Math.Clamp(float.Parse(brightness) * 100f, 0f, 100f));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
_listener.Stop();
break;
}
}
}
}
Everything in the try block runs once, and then execution goes back to the top of the loop and starts awaiting the _listener.GetContextAsync() call again. But it never does anything else, and I know for a fact the traffic it receives at localhost:8000 happens periodically. So it picks up the first one it receives, and then it just stops doing anything. It never enters the catch block, so there isn't any exception thrown.
5 Replies
djmurp
djmurp2y ago
First thing to check would be to check at which point it is not executing e.g. is it definitely staying inside the while loop? is it never returning from _listener.GetContextAsync();? It might be easier to put a Console.WriteLine at the top of the while so you can be sure it's still executing. does it work if you make Start() return a Task and return HandleIncomingConnections() directly? or the same but making it async and "await HandleIncomingConnections()" you may be "await"ing the call to HandleIncomingConnections, but you aren't awaiting the task that is executing the await
marsastro
marsastro2y ago
I've done a lot of writelines and breakpoints, so I can say with 99.9% certainty that it stops when it reaches the await _listener.GetContextAsync() during the second iteration of the loop. So it definitely stays in the while loop. Not returning from getcontextasync seems to be the issue. I'll try the thing you suggested with Start in a little bit!
djmurp
djmurp2y ago
another thing to try: since it's working the first time it means that something may be "holding on", so you might need to respond (via methods in ctx.Response). Closing the response (ctx.Response.Close()) will allow the listener to listen for a new request. It's optional to send a response depending on if your consumer (other app) needs one, but you should at least call Close() on the response object if it still fails, send the code that is calling FluxApiService.Start()
marsastro
marsastro2y ago
I'm about to try now, but I think you might be spot on with the response part I had a different version that worked, and in that version I wrote a response I probably broke something when I chose to omit responding Yup, that did the trick! Thanks for the help!
Accord
Accord2y ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server
More Posts
Is is possible to "mock" dbcontext?I would like to write some unit tests for my services. For example, let's look at my method: ``` pub✅ Where to declare relationships when you have two DBContexts?Hi! I ended up with two DBContexts in my project (ApplicationDbContext and an IdentityDbContext)... ❔ Abusing Maui for Cross Platform XR**Some context first:** I'm working on a set of templates for my code first XR app development libr❔ Use a Web server with asp.net or nothey would you all recommend using something like nginx or Apache for a asp.net site I'm currently us❔ WPF edit Label ContentHey, I want to set the label on a random position. After this I want to edit the content of the labe❔ how do i make a button that changes the current windows mouse cursor? (not only in winform)``` using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using❔ Convert.ToBase64String(array, Base64FormattingOptions.InsertLineBreaks);Hey guys! Is it possible when i convert the byte array to a string that i can add the line brakes th❔ Planning an AppWhat do you all recommend is the best way to tackle building an application? I have an idea for some❔ Strawberry Shake Prevent Null Serialization (JSON)1. Write a mutation with optional parameters, which map to optional parameters. ```graphql mutation ❔ How to convert line endings from my not encypted string to my encypted string```cs public string EncryptString(string text) { if (this._encrypt) { byte[]