C#
C#

help

Root Question Message

Mars
Mars2/4/2023
❔ ✅ 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;
            }
        }
    }
}


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.
djmurp
djmurp2/4/2023
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.
djmurp
djmurp2/4/2023
does it work if you make Start() return a Task and return HandleIncomingConnections() directly? or the same but making it async and "await HandleIncomingConnections()"
djmurp
djmurp2/4/2023
you may be "await"ing the call to HandleIncomingConnections, but you aren't awaiting the task that is executing the await
Mars
Mars2/4/2023
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
djmurp2/4/2023
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
djmurp
djmurp2/4/2023
if it still fails, send the code that is calling FluxApiService.Start()
Mars
Mars2/4/2023
I'm about to try now, but I think you might be spot on with the response part
Mars
Mars2/4/2023
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
Mars
Mars2/4/2023
Yup, that did the trick!
Mars
Mars2/4/2023
Thanks for the help!
ContactFrequently Asked QuestionsJoin The DiscordBugs & Feature RequestsTerms & Privacy