dotnet / dotnet/aspnetcore

Server-side Blazor: Consistently push to multiple circuits

Open
#17,956 4 comments 5 reactions 0 assignees View on GitHub
affected-few area-blazor Docs enhancement feature-blazor-server not-on-roadmap severity-minor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is your feature request related to a problem? Please describe.
There are several issues that ask about how we should push data to clients (e.g. https://github.com/aspnet/AspNetCore/issues/10559, https://github.com/aspnet/AspNetCore/issues/14778), and none has received a clear response so far.

The absence of documentation and guidance has fostered blogs and demos that propose odd workarounds, such as [opening a new, dedicated signalr connection to a dedicated hub from within the circuit](https://jeevasubburaj.com/2019/07/15/realtime-tic-tac-toe-blazor-game-with-bot-vs-multiplayer-using-signalr/) or [making circuits subscribe and unsubscribe to a public static delegate while praying that everything is correctly disposed](https://github.com/cores-system/BlazorChat/).

If I understand @rynowak correctly we could set up a ConcurrentQueue per circuit, have $something fill it, have a background thread drain it, and invoke StateHasChanged. However we are lacking concise instructions on thread safety in server-side blazor (should we update the "model" from the background thread and then just invoke? Does the circuit's "main task" have a synchronization context? Should we pass updated models to the circuit in a special way?), so this is not something I can use to build an app with.

### Describe the solution you'd like
The documentation should present a bulletproof scheme that allows us to easily dispatch an event to sets of circuits!

We have to be sure that
- we are not violating any thread-safety assumptions (Winforms/WPF/UWP don't allow to modify UI components without invoking the UI thread, and I could not find any documentation for server-side blazor)
- no resources are leaked (if clients disconnect, connections are aborted, ...)
- no scaling issues arise for small to medium user bases
- ordering (every user agent sees event A before event B) can be enforced
- we can handle overload situations gracefully (we want to be able to check whether A is done before we start B, because if C comes in before A is done we might want to skip B)

I am fairly certain that right now everyone developing a server-side blazor app which provides inter-circuit communication is reinventing the same wheel, and this wheel is at a crucial position in everyone's webapp, and that is awful, because most of those (including me) won't have the required internal knowledge to know the lifecycles and pitfalls of server-side blazor.

If the response is "we won't support that ourselves within the near future, please use a dedicated message broker like redis/whateverMQ" that is completely fine (and reasonable for scale out scenarios), but please provide a reliable minimal example that interested parties can use to build a prototype.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.