Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OWIN web api CancellationToken not being called

I'm using C# Web-Api with Owin, hosted as a Windows Service, to expose card reader utility.

I'm trying to use Server Sent Events. The client sends a request to open the stream, and I want to do logic when it closes(i.e the user closes the browser, or calls eventSource.close())

It looks like that:

public class CardReaderController: ApiController
{
    static ConcurrentDictionary<int, Connection> connections = new ConcurrentDictionary<int, Connection>();
    static CardReader cardReader = CardReader.Instance;

    CardReaderController() 
    {
        cardReader.OnCardRead += OnCardRead;
    }

    static void OnDisconnect(int id)
    {
        connections.TryRemove(id, out var connection);
        connection.Writer.Close();
    }

    static void OnCardRead(string cardData)
    {
        foreach(var connection in connections.Values)
            connection.Writer.WriteLine("data: " + cardData + "\n")
    }

    [HttpGet]
    public HttpResponseMessage Events(CancellationToken onDisconnect) 
    {
        ...
        int id = Request.GetHashCode();
        var response = Request.CreateResponse();
        onDisconnect.Register(() => OnDisconnect(id));

        Response.Content = new PushStreamContent((stream, content, context) => 
        {
            var connection = new Connection(new StreamWriter(stream){ AutoFlush = true });

            connection.Writer.WriteLine("data: connection started\n");
            connections.TryAdd(id, connection);
        }, "text/event-stream");

        return response;
    }
}

When testing on the localhost, everything works exactly as intended.

However, when deploying to another domain, and making the requests from there, the cancellation token isn't called, and OnDisconnect not reached.

Another weird quirk is that sometimes later, when a card is read(and causes OnCardRead to fire), after the execution of OnCardRead, it does reach OnDisconnect.

That also happens when terminating the service.

Seems like the the cancellation token does get notified, but only when another thread is executing code? But why does this only happen when sending requests from another host?

Does anyone have an explanation(and solution) to this peculiar behaviour?

like image 513
O. Aroesti Avatar asked Sep 13 '19 12:09

O. Aroesti


1 Answers

Turns out the problem actually lies in the fact the deployed version employs an Angular service worker, which causes problems on streamed requests (link), and has nothing to do with the server

like image 158
O. Aroesti Avatar answered Nov 12 '22 04:11

O. Aroesti