托管和部署 Blazor Server

主机配置值

Blazor Server 应用可以接受通用主机配置值

部署

使用 Blazor Server 托管模型,可从 ASP.NET Core 应用中在服务器上执行 Blazor。 UI 更新、事件处理和 JavaScript 调用是通过 SignalR 连接进行处理。

能够托管 ASP.NET Core 应用的 Web 服务器是必需的。 Visual Studio 包括“Blazor Server 应用”项目模板(使用 dotnet new 命令时为 blazorserver 模板)。 有关 Blazor 项目模板的更多信息,请参阅“ASP.NET Core Blazor 项目结构”。

可伸缩性

计划部署以将可用的基础设施充分用于 Blazor Server 应用。 请参阅以下资源来解决 Blazor Server 应用的可伸缩性:

部署服务器

考虑单一服务器(纵向扩展)的可伸缩性时,应用可用的内存可能是用户需求增加时应用将耗尽的第一个资源。 服务器上的可用内存影响以下因素:

  • 服务器可以支持的主动电路数。
  • 客户端上的 UI 延迟。

有关生成安全且可伸缩的 Blazor 服务器应用的指南,请参阅 ASP.NET Core Blazor Server 的威胁缓解指南

每个电路使用约 250 KB 的内存来实现至少为 Hello World 样式的应用。 电路大小取决于应用代码和与每个组件相关的状态维护要求。 我们建议你在开发应用和基础设施的过程中衡量资源需求,但在计划部署目标时可以将以下基准作为起点:如果希望应用支持 5,000 个并发用户,请考虑为应用预算至少 1.3 GB 服务器内存(或每用户 ~273 KB)。

SignalR 配置

Blazor Server 应用使用 ASP.NET Core SignalR 与浏览器进行通信。 SignalR 的托管和缩放条件适用于 Blazor Server 应用。

由于低延迟、可靠性和安全性,使用 WebSocket 作为 SignalR 传输时,Blazor 的效果最佳。 部署到 Azure 应用服务时,请在服务的 Azure 门户设置中将应用配置为使用 WebSocket。 有关为 Azure 应用服务配置应用的详细信息,请参阅 SignalR 发布指南

备注

在 ASP.NET Core 6.0 之前的版本中,在 WebSocket 传输不可用的情况下,启用长轮询作为回退传输。 如果面向 ASP.NET Core 6.0 或更高版本的应用必须使用长轮询,请参阅 ASP.NET Core Blazor SignalR 指南

有关详细信息,请参阅禁用 Blazor Server 的长轮询回退传输(ASP.NET 公告)

Azure SignalR 服务

我们建议将 Azure SignalR 服务用于 Blazor Server 应用。 该服务与应用的 Blazor 中心配合使用,以便将 Blazor Server 应用扩展到大量并发 SignalR 连接。 此外,SignalR 服务的全球覆盖和高性能数据中心可帮助显著减少由于地理位置造成的延迟。

重要

禁用 WebSocket 后,Azure 应用服务使用 HTTP 长轮询模拟实时连接。 HTTP 长轮询明显比在启用 WebSocket 的情况下运行慢,WebSocket 不使用轮询来模拟客户机-服务器连接。

建议对部署到 Azure 应用服务的 Blazor Server 应用使用 WebSocket。 默认情况下,Azure SignalR 服务使用 WebSockets。 如果应用不使用 Azure SignalR 服务,请参阅 将 ASP.NET Core SignalR 应用发布到 Azure 应用服务

从 ASP.NET Core 6.0 版本开始,默认不启用长轮询。 有关详细信息,请参阅 SignalR 配置部分。

有关详细信息,请参阅:

Configuration

若要为 SignalR 服务配置应用,应用必须支持粘滞会话;在此情况下,客户端在预呈现时被重定向回同一服务器。 将 ServerStickyMode 选项或配置值设置为 Required。 通常,应用使用下述方法之一创建配置:

  • Startup.ConfigureServices:

    services.AddSignalR().AddAzureSignalR(options =>
    {
        options.ServerStickyMode = 
        Microsoft.Azure.SignalR.ServerStickyMode.Required;
    });
    
  • 配置(使用下述方法之一):

    • appsettings.json中:

      "Azure:SignalR:StickyServerMode": "Required"
      
    • Azure 门户中的应用服务“配置” > “应用程序设置”(名称:Azure__SignalR__StickyServerMode,值:Required) 。 如果预配 Azure SignalR 服务,则为应用自动采用此方式。

预配 Azure SignalR 服务

若要在 Visual Studio 中为应用预配 Azure SignalR 服务:

  1. 在 Visual Studio 中创建适用于 Blazor Server 应用的 Azure 应用发布配置文件。
  2. Azure SignalR 服务 依赖项添加到配置文件。 如果 Azure 订阅没有要分配给应用的预先存在的 Azure SignalR 服务实例,请选择“创建新的 Azure SignalR 服务实例”以预配新的服务实例。
  3. 将应用发布到 Azure。

如果在 Visual Studio 中预配 Azure SignalR 服务,则会自动启用粘滞会话,并将 SignalR 连接字符串添加到应用服务的配置中。

IIS

使用 IIS 时,请启用:

Kubernetes

使用以下粘滞会话的 Kubernetes 注释创建入口定义:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: <ingress-name>
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"

Linux 与 Nginx

要使 SignalR Websocket 正常运行,请确保将代理的 UpgradeConnection 标头设置为以下值,并将 $connection_upgrade 映射到以下值之一:

  • 默认情况下为升级标头值。
  • 缺少升级标头或升级标头为空时为 close
http {
    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }

    server {
        listen      80;
        server_name example.com *.example.com
        location / {
            proxy_pass         http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}

有关详细信息,请参阅以下文章:

Linux 与 Apache

若要在 Linux 上托管 Apache 后面的 Blazor 应用,请为 HTTP 和 WebSocket 流量配置 ProxyPass

如下示例中:

  • Kestrel 服务器正在主机上运行。
  • 应用侦听端口 5000 上的流量。
ProxyRequests       On
ProxyPreserveHost   On
ProxyPassMatch      ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass           /_blazor ws://localhost:5000/_blazor
ProxyPass           / http://localhost:5000/
ProxyPassReverse    / http://localhost:5000/

启用以下模块:

a2enmod   proxy
a2enmod   proxy_wstunnel

检查浏览器控制台中的 WebSocket 错误。 示例错误:

  • Firefox 无法通过 ws://the-domain-name.tld/_blazor?id=XXX 与服务器建立连接。
  • 错误:未能启动传输“WebSocket”:错误:传输出现错误。
  • 错误:未能启动传输“LongPolling”:TypeError:未定义 this.transport
  • 错误:无法使用任何可用传输连接到服务器。 WebSocket 失败
  • 错误:如果连接未处于“已连接”状态,则无法发送数据。

有关详细信息,请参阅 Apache 文档

衡量网络延迟

可以使用 JS 互操作来衡量网络延迟,如以下示例所示:

@inject IJSRuntime JS

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}

为获得合理的 UI 体验,我们建议使用 250 毫秒或更低的持续 UI 延迟。

主机配置值

Blazor Server 应用可以接受通用主机配置值

部署

使用 Blazor Server 托管模型,可从 ASP.NET Core 应用中在服务器上执行 Blazor。 UI 更新、事件处理和 JavaScript 调用是通过 SignalR 连接进行处理。

能够托管 ASP.NET Core 应用的 Web 服务器是必需的。 Visual Studio 包括“Blazor Server 应用”项目模板(使用 dotnet new 命令时为 blazorserver 模板)。 有关 Blazor 项目模板的更多信息,请参阅“ASP.NET Core Blazor 项目结构”。

可伸缩性

计划部署以将可用的基础设施充分用于 Blazor Server 应用。 请参阅以下资源来解决 Blazor Server 应用的可伸缩性:

部署服务器

考虑单一服务器(纵向扩展)的可伸缩性时,应用可用的内存可能是用户需求增加时应用将耗尽的第一个资源。 服务器上的可用内存影响以下因素:

  • 服务器可以支持的主动电路数。
  • 客户端上的 UI 延迟。

有关生成安全且可伸缩的 Blazor 服务器应用的指南,请参阅 ASP.NET Core Blazor Server 的威胁缓解指南

每个电路使用约 250 KB 的内存来实现至少为 Hello World 样式的应用。 电路大小取决于应用代码和与每个组件相关的状态维护要求。 我们建议你在开发应用和基础设施的过程中衡量资源需求,但在计划部署目标时可以将以下基准作为起点:如果希望应用支持 5,000 个并发用户,请考虑为应用预算至少 1.3 GB 服务器内存(或每用户 ~273 KB)。

SignalR 配置

Blazor Server 应用使用 ASP.NET Core SignalR 与浏览器进行通信。 SignalR 的托管和缩放条件适用于 Blazor Server 应用。

由于低延迟、可靠性和安全性,使用 WebSocket 作为 SignalR 传输时,Blazor 的效果最佳。 当 WebSocket 不可用时,或在将应用显式配置为使用长轮询时,SignalR 将使用长轮询。 部署到 Azure 应用服务时,请在服务的 Azure 门户设置中将应用配置为使用 WebSocket。 有关为 Azure 应用服务配置应用的详细信息,请参阅 SignalR 发布指南

Azure SignalR 服务

我们建议将 Azure SignalR 服务用于 Blazor Server 应用。 该服务与应用的 Blazor 中心配合使用,以便将 Blazor Server 应用扩展到大量并发 SignalR 连接。 此外,SignalR 服务的全球覆盖和高性能数据中心可帮助显著减少由于地理位置造成的延迟。

重要

禁用 WebSocket 后,Azure 应用服务使用 HTTP 长轮询模拟实时连接。 HTTP 长轮询明显比在启用 WebSocket 的情况下运行慢,WebSocket 不使用轮询来模拟客户机-服务器连接。

建议对部署到 Azure 应用服务的 Blazor Server 应用使用 WebSocket。 默认情况下,Azure SignalR 服务使用 WebSockets。 如果应用不使用 Azure SignalR 服务,请参阅 将 ASP.NET Core SignalR 应用发布到 Azure 应用服务

有关详细信息,请参阅:

Configuration

若要为 SignalR 服务配置应用,应用必须支持粘滞会话;在此情况下,客户端在预呈现时被重定向回同一服务器。 将 ServerStickyMode 选项或配置值设置为 Required。 通常,应用使用下述方法之一创建配置:

  • Startup.ConfigureServices:

    services.AddSignalR().AddAzureSignalR(options =>
    {
        options.ServerStickyMode = 
        Microsoft.Azure.SignalR.ServerStickyMode.Required;
    });
    
  • 配置(使用下述方法之一):

    • appsettings.json中:

      "Azure:SignalR:StickyServerMode": "Required"
      
    • Azure 门户中的应用服务“配置” > “应用程序设置”(名称:Azure__SignalR__StickyServerMode,值:Required) 。 如果预配 Azure SignalR 服务,则为应用自动采用此方式。

预配 Azure SignalR 服务

若要在 Visual Studio 中为应用预配 Azure SignalR 服务:

  1. 在 Visual Studio 中创建适用于 Blazor Server 应用的 Azure 应用发布配置文件。
  2. Azure SignalR 服务 依赖项添加到配置文件。 如果 Azure 订阅没有要分配给应用的预先存在的 Azure SignalR 服务实例,请选择“创建新的 Azure SignalR 服务实例”以预配新的服务实例。
  3. 将应用发布到 Azure。

如果在 Visual Studio 中预配 Azure SignalR 服务,则会自动启用粘滞会话,并将 SignalR 连接字符串添加到应用服务的配置中。

IIS

使用 IIS 时,请启用:

Kubernetes

使用以下粘滞会话的 Kubernetes 注释创建入口定义:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: <ingress-name>
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"

Linux 与 Nginx

要使 SignalR Websocket 正常运行,请确保将代理的 UpgradeConnection 标头设置为以下值,并将 $connection_upgrade 映射到以下值之一:

  • 默认情况下为升级标头值。
  • 缺少升级标头或升级标头为空时为 close
http {
    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }

    server {
        listen      80;
        server_name example.com *.example.com
        location / {
            proxy_pass         http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}

有关详细信息,请参阅以下文章:

Linux 与 Apache

若要在 Linux 上托管 Apache 后面的 Blazor 应用,请为 HTTP 和 WebSocket 流量配置 ProxyPass

如下示例中:

  • Kestrel 服务器正在主机上运行。
  • 应用侦听端口 5000 上的流量。
ProxyRequests       On
ProxyPreserveHost   On
ProxyPassMatch      ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass           /_blazor ws://localhost:5000/_blazor
ProxyPass           / http://localhost:5000/
ProxyPassReverse    / http://localhost:5000/

启用以下模块:

a2enmod   proxy
a2enmod   proxy_wstunnel

检查浏览器控制台中的 WebSocket 错误。 示例错误:

  • Firefox 无法通过 ws://the-domain-name.tld/_blazor?id=XXX 与服务器建立连接。
  • 错误:未能启动传输“WebSocket”:错误:传输出现错误。
  • 错误:未能启动传输“LongPolling”:TypeError:未定义 this.transport
  • 错误:无法使用任何可用传输连接到服务器。 WebSocket 失败
  • 错误:如果连接未处于“已连接”状态,则无法发送数据。

有关详细信息,请参阅 Apache 文档

衡量网络延迟

可以使用 JS 互操作来衡量网络延迟,如以下示例所示:

@inject IJSRuntime JS

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}

为获得合理的 UI 体验,我们建议使用 250 毫秒或更低的持续 UI 延迟。

主机配置值

Blazor Server 应用可以接受通用主机配置值

部署

使用 Blazor Server 托管模型,可从 ASP.NET Core 应用中在服务器上执行 Blazor。 UI 更新、事件处理和 JavaScript 调用是通过 SignalR 连接进行处理。

能够托管 ASP.NET Core 应用的 Web 服务器是必需的。 Visual Studio 包括“Blazor Server 应用”项目模板(使用 dotnet new 命令时为 blazorserver 模板)。 有关 Blazor 项目模板的更多信息,请参阅“ASP.NET Core Blazor 项目结构”。

可伸缩性

计划部署以将可用的基础设施充分用于 Blazor Server 应用。 请参阅以下资源来解决 Blazor Server 应用的可伸缩性:

部署服务器

考虑单一服务器(纵向扩展)的可伸缩性时,应用可用的内存可能是用户需求增加时应用将耗尽的第一个资源。 服务器上的可用内存影响以下因素:

  • 服务器可以支持的主动电路数。
  • 客户端上的 UI 延迟。

有关生成安全且可伸缩的 Blazor 服务器应用的指南,请参阅 ASP.NET Core Blazor Server 的威胁缓解指南

每个电路使用约 250 KB 的内存来实现至少为 Hello World 样式的应用。 电路大小取决于应用代码和与每个组件相关的状态维护要求。 我们建议你在开发应用和基础设施的过程中衡量资源需求,但在计划部署目标时可以将以下基准作为起点:如果希望应用支持 5,000 个并发用户,请考虑为应用预算至少 1.3 GB 服务器内存(或每用户 ~273 KB)。

SignalR 配置

Blazor Server 应用使用 ASP.NET Core SignalR 与浏览器进行通信。 SignalR 的托管和缩放条件适用于 Blazor Server 应用。

由于低延迟、可靠性和安全性,使用 WebSocket 作为 SignalR 传输时,Blazor 的效果最佳。 当 WebSocket 不可用时,或在将应用显式配置为使用长轮询时,SignalR 将使用长轮询。 部署到 Azure 应用服务时,请在服务的 Azure 门户设置中将应用配置为使用 WebSocket。 有关为 Azure 应用服务配置应用的详细信息,请参阅 SignalR 发布指南

Azure SignalR 服务

我们建议将 Azure SignalR 服务用于 Blazor Server 应用。 该服务与应用的 Blazor 中心配合使用,以便将 Blazor Server 应用扩展到大量并发 SignalR 连接。 此外,SignalR 服务的全球覆盖和高性能数据中心可帮助显著减少由于地理位置造成的延迟。

重要

禁用 WebSocket 后,Azure 应用服务使用 HTTP 长轮询模拟实时连接。 HTTP 长轮询明显比在启用 WebSocket 的情况下运行慢,WebSocket 不使用轮询来模拟客户机-服务器连接。

建议对部署到 Azure 应用服务的 Blazor Server 应用使用 WebSocket。 默认情况下,Azure SignalR 服务使用 WebSockets。 如果应用不使用 Azure SignalR 服务,请参阅 将 ASP.NET Core SignalR 应用发布到 Azure 应用服务

有关详细信息,请参阅:

Configuration

若要为 SignalR 服务配置应用,应用必须支持粘滞会话;在此情况下,客户端在预呈现时被重定向回同一服务器。 将 ServerStickyMode 选项或配置值设置为 Required。 通常,应用使用下述方法之一创建配置:

  • Startup.ConfigureServices:

    services.AddSignalR().AddAzureSignalR(options =>
    {
        options.ServerStickyMode = 
        Microsoft.Azure.SignalR.ServerStickyMode.Required;
    });
    
  • 配置(使用下述方法之一):

    • appsettings.json中:

      "Azure:SignalR:StickyServerMode": "Required"
      
    • Azure 门户中的应用服务“配置” > “应用程序设置”(名称:Azure__SignalR__StickyServerMode,值:Required) 。 如果预配 Azure SignalR 服务,则为应用自动采用此方式。

预配 Azure SignalR 服务

若要在 Visual Studio 中为应用预配 Azure SignalR 服务:

  1. 在 Visual Studio 中创建适用于 Blazor Server 应用的 Azure 应用发布配置文件。
  2. Azure SignalR 服务 依赖项添加到配置文件。 如果 Azure 订阅没有要分配给应用的预先存在的 Azure SignalR 服务实例,请选择“创建新的 Azure SignalR 服务实例”以预配新的服务实例。
  3. 将应用发布到 Azure。

如果在 Visual Studio 中预配 Azure SignalR 服务,则会自动启用粘滞会话,并将 SignalR 连接字符串添加到应用服务的配置中。

IIS

使用 IIS 时,请启用:

Kubernetes

使用以下粘滞会话的 Kubernetes 注释创建入口定义:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: <ingress-name>
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"

Linux 与 Nginx

要使 SignalR Websocket 正常运行,请确保将代理的 UpgradeConnection 标头设置为以下值,并将 $connection_upgrade 映射到以下值之一:

  • 默认情况下为升级标头值。
  • 缺少升级标头或升级标头为空时为 close
http {
    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }

    server {
        listen      80;
        server_name example.com *.example.com
        location / {
            proxy_pass         http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}

有关详细信息,请参阅以下文章:

Linux 与 Apache

若要在 Linux 上托管 Apache 后面的 Blazor 应用,请为 HTTP 和 WebSocket 流量配置 ProxyPass

如下示例中:

  • Kestrel 服务器正在主机上运行。
  • 应用侦听端口 5000 上的流量。
ProxyRequests       On
ProxyPreserveHost   On
ProxyPassMatch      ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass           /_blazor ws://localhost:5000/_blazor
ProxyPass           / http://localhost:5000/
ProxyPassReverse    / http://localhost:5000/

启用以下模块:

a2enmod   proxy
a2enmod   proxy_wstunnel

检查浏览器控制台中的 WebSocket 错误。 示例错误:

  • Firefox 无法通过 ws://the-domain-name.tld/_blazor?id=XXX 与服务器建立连接。
  • 错误:未能启动传输“WebSocket”:错误:传输出现错误。
  • 错误:未能启动传输“LongPolling”:TypeError:未定义 this.transport
  • 错误:无法使用任何可用传输连接到服务器。 WebSocket 失败
  • 错误:如果连接未处于“已连接”状态,则无法发送数据。

有关详细信息,请参阅 Apache 文档

衡量网络延迟

可以使用 JS 互操作来衡量网络延迟,如以下示例所示:

@inject IJSRuntime JS

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}

为获得合理的 UI 体验,我们建议使用 250 毫秒或更低的持续 UI 延迟。