How to close EventSource connection on Firebase server using .NET HttpClient with Firebase REST Streaming API

I am using .NET HttpClient to implement Firebase Streaming Rest API, which itself supports the EventSource / Server-Sent Events protocol.

The documentation for this API is here: https://www.firebase.com/docs/rest/api/#section-streaming

My implementation shown below works correctly for connecting to Firebase and getting my data running inside a Windows service that updates its business logic itself and then calls GetAndProcessFirebaseHttpResponse as a new task every 10 minutes.

The problem is that when I look into my Firebase Dashboard, the number of concurrent connections increases by 1 each time the Task is started, and I cannot tell Firebase that the connection should be closed on the Firebase side and no further data is sent.

Here is a simplified example of my code that I entered into the sample application. Every time I call GetAndProcessFirebaseHttpResponse, another concurrent connection is increased in my Firebase panel and this connection persists even after I cancel the task (via CancellationSourceToken.Token.ThrowIfCancellationRequested ()):

    public void GetAndProcessFirebaseHttpResponse(CancellationTokenSource cancellationTokenSource)
    {
        HttpResponseMessage httpResponse = ListenAsync().Result;

        using (httpResponse)
        {
            using (Stream contentStream = httpResponse.Content.ReadAsStreamAsync().Result)
            {
                using (StreamReader contentStreamReader = new StreamReader(contentStream))
                {
                    while (true)
                    {
                        if (cancellationTokenSource.IsCancellationRequested)
                        {
                            httpResponse.RequestMessage.Dispose();
                        }

                        cancellationTokenSource.Token.ThrowIfCancellationRequested();

                        string read = contentStreamReader.ReadLineAsync().Result;

                        // Process the data here
                    }
                }
            }
        }
    }

    private async Task<HttpResponseMessage> ListenAsync()
    {
        // Create HTTP Client which will allow auto redirect as required by Firebase
        HttpClientHandler httpClientHandler = new HttpClientHandler();
        httpClientHandler.AllowAutoRedirect = true;

        HttpClient httpClient = new HttpClient(httpClientHandler, true);
        httpClient.BaseAddress = new Uri(_firebasePath);
        httpClient.Timeout = TimeSpan.FromSeconds(60);

        string requestUrl = _firebasePath + ".json?auth=" + _authSecret;
        Uri requestUri = new Uri(requestUrl);

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));

        HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        response.EnsureSuccessStatusCode();

        return response;
    }

      

Utilities HttpResponseMessage, Stream, StreamReader, HttpRequestMessage. There is no HttpClient because it is recommended that it should not be needed (see Do I need to remove HttpClient and HttpClientHandler? ). These utilities naturally allocate resources to the client , however I would assume they don't tell the Firebase server anything to close the connection to the Firebase end.

My question is, using the .NET HttpClient with the Firebase REST Streaming API, how can I communicate with the Firebase REST endpoint that I ended up connecting to, and that it should be closed on the Firebase side?

+3


source to share





All Articles