我对Blazor Server还是陌生的,并且已经设法调整默认的.Net核心项目模板来创建自己的index.html页面。
我的index.html页面连接到辅助signalR集线器,以从后端Kafka主题接收一些信息。
使用Blazor Server,如何捕获页面的关闭事件(以响应浏览器选项卡关闭,关闭浏览器或访问另一个链接),以便我可以关闭与辅助signalR集线器的连接?
namespace WebApp.Pages
{
public partial class Index : ComponentBase, IAsyncDisposable
{
private HubConnection hubConnection;
public bool IsConnected => hubConnection.State == HubConnectionState.Connected;
[Inject]
public NavigationManager NavigationManager { get; set; }
[Inject]
public IMotionDetectionRepository Repository { get; set; }
[Inject]
public ILogger<MotionDetectionConverter> LoggerMotionDetection { get; set; }
[Inject]
public ILogger<MotionInfoConverter> LoggerMotionInfo { get; set; }
[Inject]
public ILogger<JsonVisitor> LoggerJsonVisitor { get; set; }
[Inject]
public ILogger<Index> Logger { get; set; }
/// <summary>
/// Dispose of the signalR connection when page disposed
/// </summary>
public async ValueTask DisposeAsync()
{
if (hubConnection != null)
{
Logger.LogInformation("Disposing signalR connection...");
await hubConnection.DisposeAsync();
}
}
protected override async Task OnInitializedAsync()
{
var hubUrl = NavigationManager.BaseUri.TrimEnd('/') + "/motionhub";
try
{
hubConnection = new HubConnectionBuilder()
.WithUrl(hubUrl)
.ConfigureLogging(logging =>
{
logging.AddConsole();
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Information);
})
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions = JsonConvertersFactory.CreateDefaultJsonConverters(LoggerMotionDetection, LoggerMotionInfo, LoggerJsonVisitor);
})
.Build();
hubConnection.On<MotionDetection>("ReceiveMotionDetection", ReceiveMessage);
hubConnection.Closed += CloseHandler;
await hubConnection.StartAsync();
Logger.LogInformation("Index Razor Page initialised, listening on signalR hub url => " + hubUrl.ToString());
}
catch (Exception e)
{
Logger.LogError(e, "Encountered exception => " + e);
}
}
/// <remarks>
/// If this event was triggered from a connection error, the Exception that occurred will be
/// passed in as the sole argument to this handler.
/// If this event was triggered intentionally by either the client or server, then the argument
/// will be null.
/// </remarks>
private Task CloseHandler(Exception exception)
{
if (exception == null)
{
Logger.LogInformation("signalR client connection closed");
}
else
{
Logger.LogInformation($"signalR client closed due to error => {exception.Message}");
}
return Task.CompletedTask;
}
private void ReceiveMessage(MotionDetection message)
{
try
{
Logger.LogInformation("Motion detection message received");
Repository.AddItem(message);
StateHasChanged();
}
catch (Exception ex)
{
Logger.LogError(ex, "An exception was encountered => " + ex.ToString());
}
}
}
}