🔖
セッションの終了を正しく検出する (Blazor Server)
はじめに
この記事は、以下を下敷きにしています。
以下に実装例があります。
やりたいこと
セッションの終了を検出したい場合があります。
例えば、セッション数を知りたい場合に、開始で数を増やし、終了で減らす方法が考えられます。
IDispose
試行1 IDispose
を実装することで、コンポーネントの終了を検出していました。
Xxxxx.razor
@inherits IDispose
@code {
public void Dispose () {
// コンポーネントが終了した際の処理
}
}
PCのブラウザでは問題なく機能したのですが、モバイルでアプリが強制終了された際に検出できないようです。
CircuitHandler
試行2 CircuitHandler
をカスタマイズすることで、タイムアウトを含むセッションの終了を検出できました。
Program.cs
using Microsoft.AspNetCore.Components.Server.Circuits;
builder.Services.AddScoped<CircuitHandler, CircuitClosureDetector> ();
CircuitClosureDetector.cs
public class CircuitClosureDetector : CircuitHandler {
public event Action<string>? Disconnected;
public override Task OnCircuitClosedAsync (Circuit circuit, CancellationToken cancellationToken) {
Disconnected?.Invoke (circuit.Id);
if (Disconnected is not null) {
foreach (Action<string> e in Disconnected.GetInvocationList ()) {
Disconnected -= e;
}
}
return base.OnCircuitClosedAsync (circuit, cancellationToken);
}
}
Xxxxx.razor.cs
[Inject] protected CircuitHandler CircuitHandler { get; set; } = null!;
protected override async Task OnInitializedAsync () {
await base.OnInitializedAsync ();
if (CircuitHandler is CircuitClosureDetector handler) {
handler.Disconnected += id => {
// セッションが終了した際の処理
};
}
}
留意点
- ページで
CircuitHandler
をインジェクトしなくても、OnCircuitClosedAsync
は呼ばれるようです。 - ページで例外が投げられると呼ばれない場合があるので、例外への対応は別途必要です。
おわりに
お読みいただきありがとうございました。
執筆者は、Blazor、ASP.NETなど諸々において初学者ですので、誤りもあるかと思います。
お気づきの際は、是非コメントや編集リクエストにてご指摘ください。
あるいは、「それでも解らない」、「自分はこう捉えている」などといった、ご意見、ご感想も歓迎いたします。
Discussion