I'm looking for a way for this part of the code to be asynchronous.
var sse = new ServerEventsClient(apiUrl)
{
OnMessage = HandleResponse
};
I've looked at "Using C# Async/Await friendly API’s" here https://docs.servicestack.net/csharp-server-events-client#using-c-asyncawait-friendly-apis and I'm not sure if the code provided only works for one future message or every message that will come. I'll be sending a lot of requests in which I expect server responses via SSE so I'd like every response to be handled.
OnMessage
is a synchronous event which fires as soon as it receives a message, it doesn't have an async alternative callback.
If you want to handle the messages asynchronously you can decouple the producer from its consumers which can do using a BlockingCollection where you can the SSE Client capturing messages as soon as they're sent, e.g:
using var bc = new BlockingCollection<ServerEventMessage>();
using var sse = new ServerEventsClient(apiUrl) {
OnMessage = bc.Add
};
await sse.Connect();
//...
Then you can have multiple sync & async consumers handling messages at their own pace independent of how fast they're being received with Take
, TryTake
or GetConsumingEnumerable
APIs, e.g:
await Task.Run(async () => {
foreach (var msg in bc.GetConsumingEnumerable())
{
// handle msg
await Task.Delay(100);
}
});
When you want to stop handling messages (e.g. when disposing ServerEventsClient) you can notify and short-circuit consumers with:
bc.CompleteAdding();