如何在 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 程序集中检查客户端连接状态的主要内容,如果未能解决你的问题,请参考以下文章

如何将 blazor 客户端/服务器应用程序发布到 linux Web 服务器?无权访问 ssh 并且 dotnet publish 不提供 index.html

使用Jexus 容器化您的 Blazor 应用程序

如何在 ASP .NET Core Web API 中映射回退,以便 Blazor WASM 应用程序仅拦截未发送到 API 的请求

如何在 GitLab Pages 中将 Blazor WebAssembly 部署为静态站点

CORS 策略已阻止访问 fetch - Blazor 客户端 Web 程序集

如何使用 Blazor 创建独立的 Web 应用程序?