在 AWS 上部署 blazor 服务器应用程序“错误:如果连接不处于“已连接”状态,则无法发送数据。” 但可以在本地主机上运行

thu*_*nch 4 c# amazon-web-services amazon-elastic-beanstalk .net-core blazor

我有一个 blazor 服务器应用程序,它是使用 AWS Beanstalk 部署在 AWS 上的 .Net 5.0 应用程序。它是单实例部署,因此我目前无法使用负载平衡(由于当前给我的限制)。部署的环境平台是“在64位Windows Server Core 2019/2.6.3上运行的IIS 10.0”。当我在 VS2019 和本地 iis 服务器上本地运行此应用程序时,该应用程序运行良好。但是一旦部署,它就会在浏览器控制台中抛出错误:

blazor.server.js:1 [2021-02-19T17:17:03.896Z] Error: Failed to start the transport 'LongPolling': Error
e.log @ blazor.server.js:1
blazor.server.js:1 [2021-02-19T17:17:03.897Z] Error: Failed to start the connection: Error: Unable to connect to the server with any of the available transports. ServerSentEvents failed: Error: 'ServerSentEvents' does not support Binary. LongPolling failed: Error
e.log @ blazor.server.js:1
blazor.server.js:19 [2021-02-19T17:17:03.897Z] Error: Error: Unable to connect to the server with any of the available transports. ServerSentEvents failed: Error: 'ServerSentEvents' does not support Binary. LongPolling failed: Error
e.log @ blazor.server.js:19
blazor.server.js:1 Uncaught (in promise) Error: Cannot send data if the connection is not in the 'Connected' State.
    at e.send (blazor.server.js:1)
    at e.sendMessage (blazor.server.js:1)
    at e.sendWithProtocol (blazor.server.js:1)
    at blazor.server.js:1
    at new Promise (<anonymous>)
    at e.invoke (blazor.server.js:1)
    at e.<anonymous> (blazor.server.js:19)
    at blazor.server.js:19
    at Object.next (blazor.server.js:19)
    at blazor.server.js:19
Run Code Online (Sandbox Code Playgroud)

该应用程序几乎无法工作,就像当我按下按钮时,它不会按照其指示执行操作,但如果强制加载另一个页面,某些超链接按钮仍然可以工作。我使用 blazor 服务器模板启动了 blazor 应用程序,因此我在项目基本位置中有 _Imports.razor 等。

_host.cshtml

@page "/"
@namespace Space

@{
  Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>UI</title>
  <base href="~/" />
  <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
  <link href="css/site.css" rel="stylesheet" />
  <link href="_content/MatBlazor/dist/matBlazor.css" rel="stylesheet" />

  <!--Blazorise Stuff -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
  <link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
  <link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" />
</head>

<body>
  <component type="typeof(App)" render-mode="ServerPrerendered" />

  <div id="blazor-error-ui">
    <environment include="Staging,Production">
      An error has occurred. This application may no longer respond until reloaded.
    </environment>
    <environment include="Development">
      An unhandled exception has occurred. See browser dev tools for details.
    </environment>
    <a href="" class="reload">Reload</a>
    <a class="dismiss"></a>
  </div>

  <script src="_framework/blazor.server.js"></script>
  <script src="_content/MatBlazor/dist/matBlazor.js"></script>

  <!-- blazorise stuff  -->
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
  <script src="_content/Blazorise/blazorise.js"></script>
  <script src="_content/Blazorise.Bootstrap/blazorise.bootstrap.js"></script>

  <!-- Workarounds -->
  <script src="~/workaround-gradient.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

启动文件

namespace Space
{
  public class Startup
  {
    public Startup(IConfiguration configuration)
    {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
      var connectionString = AwsParameterStore.GetValue(AwsParameters.AwsConnectString) ??
                             Configuration.GetConnectionString("DefaultConnection");

      services.AddDbContext<UiContext>(options =>
          options.UseSqlServer(connectionString));

      ConfigureIdentityStuff(services);

      services.AddServerSideBlazor();
      services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<UiUser>>();
      services.AddDatabaseDeveloperPageExceptionFilter();
      services.AddBlazorDownloadFile();
      services.AddScoped<HttpClient>();
      services.AddBlazorise();
      services.AddBootstrapProviders();
      services.AddFontAwesomeIcons();
      services.AddSignalRCore();
    }

    private void ConfigureIdentityStuff(IServiceCollection services)
    {
      services.AddDefaultIdentity<UiUser>(options =>
       {
         options.SignIn.RequireConfirmedAccount = false;

         // Password settings.
         options.Password.RequireDigit = true;
         options.Password.RequireLowercase = true;
         options.Password.RequireNonAlphanumeric = true;
         options.Password.RequireUppercase = true;
         options.Password.RequiredLength = UserRelatedStaticConstDefaults.DefaultMinimumPasswordLength;
         options.Password.RequiredUniqueChars = 1;

         // Lockout settings.
         options.Lockout.DefaultLockoutTimeSpan = UserRelatedStaticConstDefaults.DefaultLockoutTime;
         options.Lockout.MaxFailedAccessAttempts = 5;
         options.Lockout.AllowedForNewUsers = true;

         // User settings.
         options.User.AllowedUserNameCharacters =
          "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
         options.User.RequireUniqueEmail = true;
       })
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<UiContext>();

      services.ConfigureApplicationCookie(options =>
       {
         // Cookie settings
         options.Cookie.HttpOnly = true;
         options.ExpireTimeSpan = TimeSpan.FromMinutes(10);

         options.LoginPath = "/Identity/Account/Login";
         options.AccessDeniedPath = "/Identity/Account/AccessDenied";
         options.SlidingExpiration = true;
       });

      services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
      services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
      services.AddRazorPages(options =>
      {
        options.Conventions.AuthorizeFolder("/Manage");
      });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

      if (env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
        app.UseMigrationsEndPoint();
      }
      else
      {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
      }

      app.UseHttpsRedirection();
      app.UseStaticFiles();

      app.UseRouting();

      app.ApplicationServices
        .UseBootstrapProviders()
        .UseFontAwesomeIcons();

      app.UseAuthentication();
      app.UseAuthorization();

      app.UseEndpoints(endpoints =>
      {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapRazorPages();
        endpoints.MapFallbackToPage("/_Host");
      });    
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我的_Imports.razor

@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using Space
@using Space.Pages
@using Space.Shared
@using Space.Shared.DataInput
@using Space.Shared.OutputData
@using MatBlazor
@using MatBlazor.Components
@using MatBlazor.Components.MatAutocompleteList
@using ReactiveUI.Blazor
@using Blazorise
@using Blazorise.Components
@attribute [Authorize]
Run Code Online (Sandbox Code Playgroud)

我根本不知道发生了什么事。我尝试查找它,但根据多个建议/答案我什么也没得到。有人可以帮忙吗!

thu*_*nch 5

Blazor 需要 Websocket。在windows beanstalk环境中,它显然默认是禁用的。

我通过使用aws 中的预定义配置启用了它们。

commands:
  InstallWebsocket:
    command: powershell.exe Install-WindowsFeature -name Web-WebSockets
  EnableWebsocket:
    command: 'C:\windows\system32\inetsrv\appcmd.exe set config "Default Web Site" -section:system.webServer/webSocket /enabled:"True" /receiveBufferLimit:"4194304" /pingInterval:"00:00:10"  /commit:apphost'
Run Code Online (Sandbox Code Playgroud)

将此配置放入.ebextensions文件夹中,一切正常。