How to Access the Current Circuit of a Blazor Server Client

Viewed 789

I am working on a Blazor Server project which uses ASP.NET Core Identity. I'm trying to implement a component to manage current active users. I can access the current identity user for current client, but I can't seem to access the circuit associated with the current client, because I want to track when each user leaves the browser (the circuit is disconnected).

From an answer by '@enet' (link), I tried implementing CircuitHandler, and I can get all the current circuits, but how can I know which circuit is associated with which user?

using Microsoft.AspNetCore.Components.Server.Circuits;
using System;
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 event EventHandler CircuitsChanged;

        protected virtual void OnCircuitsChanged()
            => CircuitsChanged?.Invoke(this, EventArgs.Empty);

        public CircuitHandlerService()
        {
             Circuits = new ConcurrentDictionary<string, Circuit>();
        }

        public override Task OnCircuitOpenedAsync(Circuit circuit, 
                             CancellationToken cancellationToken)
        {
            Circuits[circuit.Id] = circuit;
            OnCircuitsChanged();
            return base.OnCircuitOpenedAsync(circuit, cancellationToken);
        }

        public override Task OnCircuitClosedAsync(Circuit circuit, 
                             CancellationToken cancellationToken)
        {
            Circuit circuitRemoved;
            Circuits.TryRemove(circuit.Id, out circuitRemoved);
            OnCircuitsChanged();
            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);
        }
    }
}
1 Answers

If you use the AddHttpContextAccessor service

services.AddHttpContextAccessor();

You can get the the user when the circuit is created:

public class MyCircuitIdStashingHandler: CircuitHandler
{
    public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        IHttpContextAccessor accessor = new HttpContextAccessor();
        accessor.HttpContext.User.Identity; // store in dictionary somewhere
        return base.OnCircuitOpenedAsync(circuit, cancellationToken);
    }
}

...and then you can keep track on what user is using which circuit

Related