I am making a chatroom application by Blazor server-side. I want to show the online state of each user.
I have asked a question for how to get the event while closing the page in How can I get the event while page close in blazor server-side?
Now it seems the CircuitHandler is the best choice for this.
When the user closes the page, I want to set a user state from online to offline in the database. And also, the primary key of each user is temporarily storing in the index.razor.
But now after the OnCircuitClosedAsync(Circuit, CancellationToken) runs, I don't know how to invoke a method to achieve this (I can't get the variable of Blazor front-end or invoke the Blazor method of front-end).
PS: Here is the code of the back-end:
using Microsoft.AspNetCore.Components.Server.Circuits;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace BlazorCircuitHandler.Services
{
public class CircuitHandlerService : CircuitHandler
{
public ConcurrentDictionary<string, Circuit> Circuits { get; set; }
public CircuitHandlerService()
{
Circuits = new ConcurrentDictionary<string, Circuit>();
}
public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken)
{
Circuits[circuit.Id] = circuit;
return base.OnCircuitOpenedAsync(circuit, cancellationToken);
}
public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken)
{
Circuit circuitRemoved;
Circuits.TryRemove(circuit.Id, out circuitRemoved);
return base.OnCircuitClosedAsync(circuit, cancellationToken);
}
public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken)
{
return base.OnConnectionDownAsync(circuit, cancellationToken);
}
public override Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken)
{
return base.OnConnectionUpAsync(circuit, cancellationToken);
}
}
}
And here is the front-end:
@page "/"
@using Microsoft.AspNetCore.Components.Server.Circuits
@inject CircuitHandler CircuitHandlerService
<h1>Hello, world!</h1>
Welcome to your new app.
<p>
Number of Circuits: @((CircuitHandlerService as BlazorCircuitHandler.Services.CircuitHandlerService).Circuits.Count)
<ul>
@foreach (var circuit in (CircuitHandlerService as BlazorCircuitHandler.Services.CircuitHandlerService).Circuits)
{
<li>@circuit.Key</li>
}
</ul>
@{
var PrimaryKey = "abcdefg";
}
</p>
Would you please help me? Thank you.
This should be working, I guess ;)
CircuitHandlerService.cs
Usage
Startup.cs
Note: To verify that it is working run the app. Then open another two tabs. Now, close the first tab you open (left to right), then the second. Notice the display of the number of active circuits...