如何在 Blazor Web 程序集中检查客户端连接状态

Posted

技术标签:

【中文标题】如何在 Blazor Web 程序集中检查客户端连接状态【英文标题】:how to Check Client connection status in Blazor web assembly 【发布时间】:2021-12-08 17:19:54 【问题描述】:

我有一个 Blazor webbasemmbly 应用程序,它使用 asp.net 核心作为后端,使用 Blazor wasm 作为前端。我有一个类可以检查 HTTP 问题,例如 notfound、BadReqest 和 ...

  public class HttpInterceptorService
    
        private readonly HttpClientInterceptor _interceptor;
        private readonly NavigationManager _navManager;
        
        private readonly RefreshTokenService _refreshTokenService;
        
        public HttpInterceptorService(HttpClientInterceptor interceptor,
            NavigationManager navManager, 
            RefreshTokenService refreshTokenService)
        
            _interceptor = interceptor;
            _navManager = navManager;               
            _refreshTokenService = refreshTokenService;
        

        public void RegisterEvent() => _interceptor.AfterSend += HandleResponse;
        public void RegisterBeforeSendEvent() =>
            _interceptor.BeforeSendAsync += InterceptBeforeSendAsync;

        public void DisposeEvent()
        
            _interceptor.AfterSend -= HandleResponse;
            _interceptor.BeforeSendAsync -= InterceptBeforeSendAsync;
        

        private async Task InterceptBeforeSendAsync(object sender,
            HttpClientInterceptorEventArgs e)
        
            var absolutePath = e.Request.RequestUri.AbsolutePath;

            if (!absolutePath.Contains("token") && !absolutePath.Contains("account"))
            
                var token = await _refreshTokenService.TryRefreshToken();
                if (!string.IsNullOrEmpty(token))
                
                    e.Request.Headers.Authorization =
                        new AuthenticationHeaderValue("bearer", token);
                
            
        

        private void HandleResponse(object sender, HttpClientInterceptorEventArgs e)
        
            if (e.Response == null)
            
                _navManager.NavigateTo("/PageError");
                throw new HttpResponseException("Server not available.");
            

            var message = "";

            if (!e.Response.IsSuccessStatusCode)
            
                
                switch (e.Response.StatusCode)
                
                    case HttpStatusCode.NotFound:
                        _navManager.NavigateTo("/Page404");                 
                        break;
                    case HttpStatusCode.BadRequest:                                 
                        break;
                    case HttpStatusCode.Unauthorized:
                        _navManager.NavigateTo("/unauthorized");                    
                        break;
                    default:
                        _navManager.NavigateTo("/PageError");                   
                        break;
                

                throw new HttpResponseException(message);
            
               
    

这个 HTTP 拦截器做得很好,但问题是当客户端应用程序 (wasm) 失去与服务器的连接时(出于任何原因,例如没有互联网,或服务器停止运行......),它不会工作,不会有用。 当服务器不能正常运行时。

所以搜索我发现我们必须检查 signalR 连接状态,但我找不到有关如何实现它的示例或教程。

我想将它全局添加到应用程序中。

【问题讨论】:

我不确定 signalr 是否能满足您的要求,但如果您愿意尝试,我认为this document 会有所帮助。 我以前试过,但没有帮助。 【参考方案1】:

首先,在您的服务器项目中创建一个集线器。

https://docs.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-5.0

Startup.cs

public void ConfigureServices(IServiceCollection services)

    services.AddSignalR();


public void Configure(IApplicationBuilder app)

    app.UseEndpoints(endpoints =>
    
        endpoints.MapHub<MyHub>("/myhub");
    );

MyHub

public class MyHub : Hub


然后,在您的 WASM 客户端中创建一个服务来管理集线器连接:

public class SignalRClientService

    HubConnection MyHubConnection;
    NavigationManager NavigationManager;

    public SignalRClientService(NavigationManager navigationManager)
    
        NavigationManager = navigationManager;

        OpenHub();
    

    public void OpenHub()
    
        MyHubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/myhub")
            .Build();

        MyHubConnection.Closed += async (error) =>
        
            // Do what you need to do ...
            // e.g. 1) Inject this service into your razor component
            //      2) Raise an event from here that connection closed
            //      3) Listen for event in razor component
            //      4) Tell user that connection is closed.

            // You could then try to reinitialize the connection here
            // and raise and event that connection is reestablished.
        
    

在 Program.cs 中注册服务

builder.Services.AddSingleton<SignalRClientService>();

【讨论】:

以上是关于如何在 Blazor Web 程序集中检查客户端连接状态的主要内容,如果未能解决你的问题,请参考以下文章