web-dev-qa-db-ja.com

Blazorサーバー側のCircuitHandlerでメソッドを呼び出すにはどうすればよいですか?

Blazorサーバーサイドでチャットルームアプリを作っています。各ユーザーのオンライン状態を表示したい。

私はページを閉じるときにイベントを取得する方法について質問しました ブレザーサーバー側でページを閉じるときにイベントを取得するにはどうすればよいですか?

現在、CircuitHandlerがこれに最適な選択です。

ユーザーがページを閉じたときに、データベースでユーザーの状態をオンラインからオフラインに設定したいと考えています。また、各ユーザーの主キーは、一時的に_index.razor_に格納されます。

しかし、OnCircuitClosedAsync(Circuit, CancellationToken)の実行後、これを達成するためのメソッドを呼び出す方法がわかりません(Blazorフロントエンドの変数を取得したり、フロントエンドのBlazorメソッドを呼び出すことができません)。

PS:これがバックエンドのコードです:

_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);
        }
    }
}
_

そして、これがフロントエンドです:

_@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>
_

手伝ってくれませんか?ありがとうございました。

6
Melon NG

回路ハンドラー内でイベントを公開するだけです。

public class CircuitHandlerService : CircuitHandler
{
    public event EventHandler CircuitsChanged;

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

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

    public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        Circuits.TryRemove(circuit.Id, out var circuitRemoved);
        OnCircuitsChanged();
        return Task.CompletedTask;
    }
}

次に、Razorコンポーネントで、そのイベントをサブスクライブし、必要に応じてUIを更新できます。

@implements IDisposable
@inject CircuitHandler circuitHandler

<ul>
    @foreach (var circuit in Circuits)
    {
        <li>@circuit.Key</li>
    }
</ul>

@code {
    private IDictionary<string, Circuit> Circuits
        => (circuitHandler as CircuitHandlerService).Circuits;

    protected override void OnInitialized()
    {
        // register event handler
        (circuitHandler as CircuitHandlerService).CircuitsChanged += HandleCircuitsChanged;
    }

    public void Dispose()
    {
        // unregister the event handler when the component is destroyed
        (circuitHandler as CircuitHandlerService).CircuitsChanged -= HandleCircuitsChanged;
    }

    public void HandleCircuitsChanged(object sender, EventArgs args)
    {
        // notify the UI that the state has changed
        StateHasChanged();
    }
}
0
poke