ASP.NET Core SignalR 配置

本文介绍 ASP.NET Core SignalR 配置。

有关补充或取代本文中指南的 BlazorSignalR 指南,请参阅 ASP.NET Core BlazorSignalR 指南

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化。 可将 AddJsonProtocol 添加到 Startup.ConfigureServices 中的 AddSignalR 之后。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerOptions 属性是一个 System.Text.Json JsonSerializerOptions 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 System.Text.Json 文档

例如,要将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称,请在 Program.cs 中使用以下代码:

builder.Services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

切换到 Newtonsoft.Json

如果需要 System.Text.Json 中不支持的 Newtonsoft.Json 功能,请参阅切换到 Newtonsoft.Json

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。
StreamBufferCapacity 10 可以为客户端上传流缓冲的最大项数。 如果达到此限制,将阻止对调用的处理,直到服务器处理了流项。
MaximumReceiveMessageSize 32 KB 单个传入中心消息的最大大小。 提高此值可能会增加拒绝服务 (DoS) 攻击风险。
MaximumParallelInvocationsPerClient 1 在排队之前,每个客户端可以并行调用的中心方法的最大数量。
DisableImplicitFromServicesParameters false 如果可能,将从 DI 解析中心方法参数。

可以通过在 Program.cs 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

 builder.Services.AddSignalR(hubOptions =>
 {
     hubOptions.EnableDetailedErrors = true;
     hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
 });

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

builder.Services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Program.cs 中的 MapHub 来配置这些选项。

using Microsoft.AspNetCore.Http.Connections;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();
app.MapHub<ChatHub>("/chathub", options =>
{
    options.Transports =
        HttpTransportType.WebSockets |
        HttpTransportType.LongPolling;
}
);
app.Run();

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 64 KB 在应用反压之前,服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
TransportMaxBufferSize 64 KB 服务器在观察到反压之前所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。
MinimumProtocolVersion 0 指定协商协议的最低版本。 这用于将客户端限制为较新版本。
CloseOnAuthenticationExpiration false 设置此选项以启用身份验证过期跟踪,此设置会在令牌过期时关闭连接。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

还可以提供表示日志级别名称的 string 值,而不是 LogLevel 值。 当在无法访问 LogLevel 常量的环境中配置 SignalR 日志记录时,这非常有用。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging("warn")
    .build();

下表列出了可用的日志级别。 提供给 configureLogging 的值用于设置要记录的日志的最小级别。 将记录此级别的或表中该级别后面列出的级别的消息。

String LogLevel
trace LogLevel.Trace
debug LogLevel.Debug
info or information LogLevel.Information
warn or warning LogLevel.Warning
error LogLevel.Error
critical LogLevel.Critical
none LogLevel.None

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

在 Java 客户端中,通过 HttpHubConnectionBuilder 上的 withTransport 方法来选择传输。 Java 客户端默认使用 WebSocket 传输。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withTransport(TransportEnum.WEBSOCKETS)
    .build();

注意

SignalR Java 客户端尚不支持传输回退。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

用于配置超时和保持连接行为的其他选项:

选项 默认值 说明
WithServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时,可直接在 HubConnectionBuilder 上进行设置。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器的保持连接间隔 (WithKeepAliveInterval) 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时,在 HubConnection 对象本身上可用。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
WithKeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔,可直接在 HubConnectionBuilder 上进行设置。 使用此设置,服务器可以检测强行断开连接的情况,例如客户断开其计算机的网络连接。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

以下示例显示的值是默认值的两倍:

var builder = new HubConnectionBuilder()
    .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
    .WithServerTimeout(TimeSpan.FromSeconds(60))
    .WithKeepAliveInterval(TimeSpan.FromSeconds(30))
    .Build();

builder.On<string, string>("ReceiveMessage", (user, message) => ...

await builder.StartAsync();

配置监控状态的重新连接

SignalR 有状态重新连接可减少客户端遇到暂时断开网络连接(例如,切换网络连接时或短暂的暂时失去访问权限时)情况时感知到的停机时间。

有状态重新连接可通过以下方式实现此目的:

  • 暂时缓冲服务器和客户端上的数据。
  • 确认服务器和客户端(确认)收到的消息。
  • 识别连接何时启动并重播在连接关闭时可能已发送的消息。

ASP.NET Core 8.0 及更高版本支持监控状态的重新连接。

在服务器中心终结点和客户端处选择加入监控状态的重新连接:

  • 更新服务器中心终结点配置以启用 AllowStatefulReconnects 选项:

    app.MapHub<MyHub>("/hubName", options =>
    {
        options.AllowStatefulReconnects = true;
    });
    

    (可选)可以全局设置服务器允许的最大缓冲区大小(以字节为单位),也可以使用 StatefulReconnectBufferSize 选项针对特定的中心进行设置:

    全局设置的 StatefulReconnectBufferSize 选项:

    builder.AddSignalR(o => o.StatefulReconnectBufferSize = 1000);
    

    针对特定中心进行设置的 StatefulReconnectBufferSize 选项:

    builder.AddSignalR().AddHubOptions<MyHub>(o => o.StatefulReconnectBufferSize = 1000);
    

    StatefulReconnectBufferSize 选项是可选的,默认值为 100,000 字节。

  • 更新 JavaScript 或 TypeScript 客户端代码,以启用 withStatefulReconnect 选项:

    const builder = new signalR.HubConnectionBuilder()
      .withUrl("/hubname")
      .withStatefulReconnect({ bufferSize: 1000 });  // Optional, defaults to 100,000
    const connection = builder.build();
    

    bufferSize 选项是可选的,默认值为 100,000 字节。

  • 更新 .NET 客户端代码以启用 WithStatefulReconnect 选项:

      var builder = new HubConnectionBuilder()
          .WithUrl("<hub url>")
          .WithStatefulReconnect();
      builder.Services.Configure<HubConnectionOptions>(o => o.StatefulReconnectBufferSize = 1000);
      var hubConnection = builder.Build();
    

    StatefulReconnectBufferSize 选项是可选的,默认值为 100,000 字节。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。
ApplicationMaxBufferSize 1 MB 在应用反压之前,客户端所缓冲的从服务器接收到的字节的最大数目。 增大此值可使客户端更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
TransportMaxBufferSize 1 MB 客户端在观察到反压之前所缓冲的由用户应用程序发送的字节的最大数目。 增大此值可使客户端更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.SkipNegotiation = true;
        options.Transports = HttpTransportType.WebSockets;
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        // "Foo: Bar" will not be sent with WebSockets or Server-Sent Events requests
        headers: { "Foo": "Bar" },
        transport: signalR.HttpTransportType.LongPolling 
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化,可以在 Startup.ConfigureServices 方法的 AddSignalR 之后添加该扩展方法。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerSettings 属性是一个 Json.NET JsonSerializerSettings 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 Json.NET 文档

例如,要将序列化程序配置为“PascalCase”属性名称,而不使用默认的大小写名称,请在 Startup.ConfigureServices 中使用以下代码:

services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerSettings.ContractResolver =
            new DefaultContractResolver();
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerSettings.ContractResolver =
            new DefaultContractResolver();
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。

可以通过在 Startup.ConfigureServices 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
    });
}

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Startup.Configure 中的 MapHub 来配置这些选项。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSignalR((configure) =>
    {
        var desiredTransports =
            HttpTransportType.WebSockets |
            HttpTransportType.LongPolling;

        configure.MapHub<ChatHub>("/chathub", (options) =>
        {
            options.Transports = desiredTransports;
        });
    });
}

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 32 KB 服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器接收更大的消息,但可能会对内存消耗产生负面影响。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
TransportMaxBufferSize 32 KB 服务器所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器发送更大的消息,但可能会对内存消耗产生负面影响。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化,可以在 Startup.ConfigureServices 方法的 AddSignalR 之后添加该扩展方法。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerSettings 属性是一个 Json.NET JsonSerializerSettings 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 Json.NET 文档

例如,要将序列化程序配置为“PascalCase”属性名称,而不使用默认的大小写名称,请在 Startup.ConfigureServices 中使用以下代码:

services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerSettings.ContractResolver =
            new DefaultContractResolver();
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerSettings.ContractResolver =
            new DefaultContractResolver();
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。

可以通过在 Startup.ConfigureServices 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
    });
}

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Startup.Configure 中的 MapHub 来配置这些选项。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSignalR((configure) =>
    {
        var desiredTransports =
            HttpTransportType.WebSockets |
            HttpTransportType.LongPolling;

        configure.MapHub<ChatHub>("/chathub", (options) =>
        {
            options.Transports = desiredTransports;
        });
    });
}

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 32 KB 服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器接收更大的消息,但可能会对内存消耗产生负面影响。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
TransportMaxBufferSize 32 KB 服务器所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器发送更大的消息,但可能会对内存消耗产生负面影响。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化。 可将 AddJsonProtocol 添加到 Startup.ConfigureServices 中的 AddSignalR 之后。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerOptions 属性是一个 System.Text.Json JsonSerializerOptions 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 System.Text.Json 文档

例如,要将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称,请在 Startup.ConfigureServices 中使用以下代码:

services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

切换到 Newtonsoft.Json

如果需要 System.Text.Json 中不支持的 Newtonsoft.Json 功能,请参阅切换到 Newtonsoft.Json

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。
StreamBufferCapacity 10 可以为客户端上传流缓冲的最大项数。 如果达到此限制,将阻止对调用的处理,直到服务器处理了流项。
MaximumReceiveMessageSize 32 KB 单个传入中心消息的最大大小。 提高此值可能会增加拒绝服务(DoS) 攻击风险。

可以通过在 Startup.ConfigureServices 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
    });
}

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Startup.Configure 中的 MapHub 来配置这些选项。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chathub", options =>
        {
            options.Transports =
                HttpTransportType.WebSockets |
                HttpTransportType.LongPolling;
        });
    });
}

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 32 KB 在应用反压之前,服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
TransportMaxBufferSize 32 KB 服务器在观察到反压之前所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

还可以提供表示日志级别名称的 string 值,而不是 LogLevel 值。 当在无法访问 LogLevel 常量的环境中配置 SignalR 日志记录时,这非常有用。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging("warn")
    .build();

下表列出了可用的日志级别。 提供给 configureLogging 的值用于设置要记录的日志的最小级别。 将记录此级别的或表中该级别后面列出的级别的消息。

String LogLevel
trace LogLevel.Trace
debug LogLevel.Debug
info or information LogLevel.Information
warn or warning LogLevel.Warning
error LogLevel.Error
critical LogLevel.Critical
none LogLevel.None

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

在 Java 客户端中,通过 HttpHubConnectionBuilder 上的 withTransport 方法来选择传输。 Java 客户端默认使用 WebSocket 传输。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withTransport(TransportEnum.WEBSOCKETS)
    .build();

注意

SignalR Java 客户端尚不支持传输回退。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化。 可将 AddJsonProtocol 添加到 Startup.ConfigureServices 中的 AddSignalR 之后。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerOptions 属性是一个 System.Text.Json JsonSerializerOptions 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 System.Text.Json 文档

例如,要将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称,请在 Startup.ConfigureServices 中使用以下代码:

services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

切换到 Newtonsoft.Json

如果需要 System.Text.Json 中不支持的 Newtonsoft.Json 功能,请参阅切换到 Newtonsoft.Json

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。
StreamBufferCapacity 10 可以为客户端上传流缓冲的最大项数。 如果达到此限制,将阻止对调用的处理,直到服务器处理了流项。
MaximumReceiveMessageSize 32 KB 单个传入中心消息的最大大小。 提高此值可能会增加拒绝服务(DoS) 攻击风险。

可以通过在 Startup.ConfigureServices 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
    });
}

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Startup.Configure 中的 MapHub 来配置这些选项。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chathub", options =>
        {
            options.Transports =
                HttpTransportType.WebSockets |
                HttpTransportType.LongPolling;
        });
    });
}

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 32 KB 在应用反压之前,服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
TransportMaxBufferSize 32 KB 服务器在观察到反压之前所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。
MinimumProtocolVersion 0 指定协商协议的最低版本。 这用于将客户端限制为较新版本。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

还可以提供表示日志级别名称的 string 值,而不是 LogLevel 值。 当在无法访问 LogLevel 常量的环境中配置 SignalR 日志记录时,这非常有用。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging("warn")
    .build();

下表列出了可用的日志级别。 提供给 configureLogging 的值用于设置要记录的日志的最小级别。 将记录此级别的或表中该级别后面列出的级别的消息。

String LogLevel
trace LogLevel.Trace
debug LogLevel.Debug
info or information LogLevel.Information
warn or warning LogLevel.Warning
error LogLevel.Error
critical LogLevel.Critical
none LogLevel.None

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

在 Java 客户端中,通过 HttpHubConnectionBuilder 上的 withTransport 方法来选择传输。 Java 客户端默认使用 WebSocket 传输。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withTransport(TransportEnum.WEBSOCKETS)
    .build();

注意

SignalR Java 客户端尚不支持传输回退。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化。 可将 AddJsonProtocol 添加到 Startup.ConfigureServices 中的 AddSignalR 之后。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerOptions 属性是一个 System.Text.Json JsonSerializerOptions 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 System.Text.Json 文档

例如,要将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称,请在 Startup.ConfigureServices 中使用以下代码:

services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

切换到 Newtonsoft.Json

如果需要 System.Text.Json 中不支持的 Newtonsoft.Json 功能,请参阅切换到 Newtonsoft.Json

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。
StreamBufferCapacity 10 可以为客户端上传流缓冲的最大项数。 如果达到此限制,将阻止对调用的处理,直到服务器处理了流项。
MaximumReceiveMessageSize 32 KB 单个传入中心消息的最大大小。 提高此值可能会增加拒绝服务(DoS) 攻击风险。
MaximumParallelInvocationsPerClient 1 在排队之前,每个客户端可以并行调用的中心方法的最大数量。

可以通过在 Startup.ConfigureServices 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
    });
}

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Startup.Configure 中的 MapHub 来配置这些选项。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chathub", options =>
        {
            options.Transports =
                HttpTransportType.WebSockets |
                HttpTransportType.LongPolling;
        });
    });
}

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 32 KB 在应用反压之前,服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
TransportMaxBufferSize 32 KB 服务器在观察到反压之前所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。
MinimumProtocolVersion 0 指定协商协议的最低版本。 这用于将客户端限制为较新版本。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

还可以提供表示日志级别名称的 string 值,而不是 LogLevel 值。 当在无法访问 LogLevel 常量的环境中配置 SignalR 日志记录时,这非常有用。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging("warn")
    .build();

下表列出了可用的日志级别。 提供给 configureLogging 的值用于设置要记录的日志的最小级别。 将记录此级别的或表中该级别后面列出的级别的消息。

String LogLevel
trace LogLevel.Trace
debug LogLevel.Debug
info or information LogLevel.Information
warn or warning LogLevel.Warning
error LogLevel.Error
critical LogLevel.Critical
none LogLevel.None

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

在 Java 客户端中,通过 HttpHubConnectionBuilder 上的 withTransport 方法来选择传输。 Java 客户端默认使用 WebSocket 传输。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withTransport(TransportEnum.WEBSOCKETS)
    .build();

注意

SignalR Java 客户端尚不支持传输回退。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.SkipNegotiation = true;
        options.Transports = HttpTransportType.WebSockets;
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        // "Foo: Bar" will not be sent with WebSockets or Server-Sent Events requests
        headers: { "Foo": "Bar" },
        transport: signalR.HttpTransportType.LongPolling 
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化。 可将 AddJsonProtocol 添加到 Program.cs 中的 AddSignalR 之后。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerOptions 属性是一个 System.Text.Json JsonSerializerOptions 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 System.Text.Json 文档

例如,要将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称,请在 Program.cs 中使用以下代码:

builder.Services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

切换到 Newtonsoft.Json

如果需要 System.Text.Json 中不支持的 Newtonsoft.Json 功能,请参阅切换到 Newtonsoft.Json

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。
StreamBufferCapacity 10 可以为客户端上传流缓冲的最大项数。 如果达到此限制,将阻止对调用的处理,直到服务器处理了流项。
MaximumReceiveMessageSize 32 KB 单个传入中心消息的最大大小。 提高此值可能会增加拒绝服务(DoS) 攻击风险。
MaximumParallelInvocationsPerClient 1 在排队之前,每个客户端可以并行调用的中心方法的最大数量。

可以通过在 Program.cs 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

builder.Services.AddSignalR(hubOptions =>
{
    hubOptions.EnableDetailedErrors = true;
    hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
});

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

builder.Services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Program.cs 中的 MapHub 来配置这些选项。

using Microsoft.AspNetCore.Http.Connections;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();
app.MapHub<ChatHub>("/chathub", options =>
{
    options.Transports =
        HttpTransportType.WebSockets |
        HttpTransportType.LongPolling;
}
);
app.Run();

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 64 KB 在应用反压之前,服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
TransportMaxBufferSize 64 KB 服务器在观察到反压之前所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。
MinimumProtocolVersion 0 指定协商协议的最低版本。 这用于将客户端限制为较新版本。
CloseOnAuthenticationExpiration false 设置此选项以启用身份验证过期跟踪,此设置会在令牌过期时关闭连接。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

还可以提供表示日志级别名称的 string 值,而不是 LogLevel 值。 当在无法访问 LogLevel 常量的环境中配置 SignalR 日志记录时,这非常有用。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging("warn")
    .build();

下表列出了可用的日志级别。 提供给 configureLogging 的值用于设置要记录的日志的最小级别。 将记录此级别的或表中该级别后面列出的级别的消息。

String LogLevel
trace LogLevel.Trace
debug LogLevel.Debug
info or information LogLevel.Information
warn or warning LogLevel.Warning
error LogLevel.Error
critical LogLevel.Critical
none LogLevel.None

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

在 Java 客户端中,通过 HttpHubConnectionBuilder 上的 withTransport 方法来选择传输。 Java 客户端默认使用 WebSocket 传输。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withTransport(TransportEnum.WEBSOCKETS)
    .build();

注意

SignalR Java 客户端尚不支持传输回退。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。
ApplicationMaxBufferSize 1 MB 在应用反压之前,客户端所缓冲的从服务器接收到的字节的最大数目。 增大此值可使客户端更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
TransportMaxBufferSize 1 MB 客户端在观察到反压之前所缓冲的由用户应用程序发送的字节的最大数目。 增大此值可使客户端更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.SkipNegotiation = true;
        options.Transports = HttpTransportType.WebSockets;
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        // "Foo: Bar" will not be sent with WebSockets or Server-Sent Events requests
        headers: { "Foo": "Bar" },
        transport: signalR.HttpTransportType.LongPolling 
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源

JSON/MessagePack 序列化选项

ASP.NET Core SignalR 支持两个用于消息编码的协议:JSONMessagePack。 每个协议都提供序列化配置选项。

可以使用 AddJsonProtocol 扩展方法在服务器上配置 JSON 序列化。 可将 AddJsonProtocol 添加到 Startup.ConfigureServices 中的 AddSignalR 之后。 AddJsonProtocol 方法采用接收 options 对象的委托。 该对象上的 PayloadSerializerOptions 属性是一个 System.Text.Json JsonSerializerOptions 对象,可用于配置参数和返回值的序列化。 有关详细信息,请参阅 System.Text.Json 文档

例如,要将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称,请在 Program.cs 中使用以下代码:

builder.Services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

在 .NET 客户端中,HubConnectionBuilder 上有相同的 AddJsonProtocol 扩展方法。 必须导入 Microsoft.Extensions.DependencyInjection 命名空间来解析扩展方法:

// At the top of the file:
using Microsoft.Extensions.DependencyInjection;

// When constructing your connection:
var connection = new HubConnectionBuilder()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    })
    .Build();

注意

目前无法配置 JavaScript 客户端中的 JSON 序列化。

切换到 Newtonsoft.Json

如果需要 System.Text.Json 中不支持的 Newtonsoft.Json 功能,请参阅切换到 Newtonsoft.Json

MessagePack 序列化选项

可以通过向 AddMessagePackProtocol 调用提供委托来配置 MessagePack 序列化。 有关更多详细信息,请参阅 SignalR 中的 MessagePack

注意

目前无法配置 JavaScript 客户端中的 MessagePack 序列化。

配置服务器选项

下表描述了用于配置 SignalR 中心的选项:

选项 默认值 说明
ClientTimeoutInterval 30 秒 如果在此间隔时间内未收到消息(包括保持连接状态),服务器将认为客户端已断开连接。 由于实现方式的不同,将客户端标记为断开连接可能需要更长的超时间隔时间。 建议的值为 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 如果客户端在此时间间隔内未发送初始握手消息,则连接将关闭。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 如果服务器在此间隔内未发送消息,将自动发送 ping 消息以保持连接处于开启状态。 更改 KeepAliveInterval 时,请更改客户端上的 ServerTimeoutserverTimeoutInMilliseconds 设置。 建议的 ServerTimeoutserverTimeoutInMilliseconds 值是 KeepAliveInterval 值的两倍。
SupportedProtocols 所有已安装的协议 此中心支持的协议。 默认情况下,允许在服务器上注册的所有协议。 可以从此列表中删除协议,以针对单个中心禁用特定协议。
EnableDetailedErrors false 如果为 true,则当中心方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false,因为这些异常消息可能包含敏感信息。
StreamBufferCapacity 10 可以为客户端上传流缓冲的最大项数。 如果达到此限制,将阻止对调用的处理,直到服务器处理了流项。
MaximumReceiveMessageSize 32 KB 单个传入中心消息的最大大小。 提高此值可能会增加拒绝服务(DoS) 攻击风险。
MaximumParallelInvocationsPerClient 1 在排队之前,每个客户端可以并行调用的中心方法的最大数量。
DisableImplicitFromServicesParameters false 如果可能,将从 DI 解析中心方法参数。

可以通过在 Program.cs 中向 AddSignalR 调用提供选项委托,为所有中心配置选项。

 builder.Services.AddSignalR(hubOptions =>
 {
     hubOptions.EnableDetailedErrors = true;
     hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1);
 });

用于单个中心的选项会替代 AddSignalR 中提供的全局选项,可以使用 AddHubOptions 进行配置:

builder.Services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
    options.EnableDetailedErrors = true;
});

高级 HTTP 配置选项

使用 HttpConnectionDispatcherOptions 配置与传输和内存缓冲区管理相关的高级设置。 通过将委托传递给 Program.cs 中的 MapHub 来配置这些选项。

using Microsoft.AspNetCore.Http.Connections;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();
app.MapHub<ChatHub>("/chathub", options =>
{
    options.Transports =
        HttpTransportType.WebSockets |
        HttpTransportType.LongPolling;
}
);
app.Run();

下表介绍了用于配置 ASP.NET Core SignalR 的高级 HTTP 选项的选项:

选项 默认值 说明
ApplicationMaxBufferSize 64 KB 在应用反压之前,服务器所缓冲的从客户端接收到的字节的最大数目。 增大此值可使服务器更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
TransportMaxBufferSize 64 KB 服务器在观察到反压之前所缓冲的由应用发送的字节的最大数目。 增大此值可使服务器更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。
AuthorizationData 从应用于中心类的 Authorize 属性自动收集的数据。 用于确定客户端是否有权连接到中心的 IAuthorizeData 对象的列表。
Transports 所有传输都已启用。 位标志 HttpTransportType 值的枚举,这些值可限制客户端用于连接的传输。
LongPolling 请参阅下文。 特定于长轮询传输的其他选项。
WebSockets 请参阅下文。 特定于 WebSocket 传输的其他选项。
MinimumProtocolVersion 0 指定协商协议的最低版本。 这用于将客户端限制为较新版本。
CloseOnAuthenticationExpiration false 设置此选项以启用身份验证过期跟踪,此设置会在令牌过期时关闭连接。

长轮询传输提供可使用 LongPolling 属性配置的其他选项:

选项 默认值 说明
PollTimeout 90 秒 服务器在终止单个轮询请求之前等待消息发送到客户端的最长等待时间。 减小此值会导致客户端更频繁地发出新的轮询请求。

WebSocket 传输提供可使用 WebSockets 属性配置的其他选项:

选项 默认值 说明
CloseTimeout 5 秒 服务器关闭后,如果客户端未能在此时间间隔内关闭,则连接将终止。
SubProtocolSelector null 一个委托,可用于将 Sec-WebSocket-Protocol 标头设置为自定义值。 该委托接收客户端请求的值作为输入,并预期返回所需的值。

配置客户端选项

可以在 HubConnectionBuilder 类型上配置客户端选项(适用于 .NET 和 JavaScript 客户端)。 Java 客户端中也适用,但包含生成器配置选项的是 HttpHubConnectionBuilder 子类以及 HubConnection 本身。

配置日志记录

.NET 客户端中的日志记录是使用 ConfigureLogging 方法配置的。 提供程序和筛选器的注册方式与它们在服务器上的注册方式相同。 有关详细信息,请参阅 ASP.NET Core 中的日志记录文档。

注意

若要注册日志记录提供程序,需要安装必要的包。 有关完整列表,请参阅文档的内置日志提供程序部分。

例如,要启用控制台日志记录,则安装 Microsoft.Extensions.Logging.Console NuGet 包。 调用 AddConsole 扩展方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub")
    .ConfigureLogging(logging => {
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddConsole();
    })
    .Build();

在 JavaScript 客户端中,存在类似的 configureLogging 方法。 提供一个 LogLevel 值,该值指示要生成的日志消息的最小级别。 日志将写入浏览器控制台窗口。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

还可以提供表示日志级别名称的 string 值,而不是 LogLevel 值。 当在无法访问 LogLevel 常量的环境中配置 SignalR 日志记录时,这非常有用。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging("warn")
    .build();

下表列出了可用的日志级别。 提供给 configureLogging 的值用于设置要记录的日志的最小级别。 将记录此级别的或表中该级别后面列出的级别的消息。

String LogLevel
trace LogLevel.Trace
debug LogLevel.Debug
info or information LogLevel.Information
warn or warning LogLevel.Warning
error LogLevel.Error
critical LogLevel.Critical
none LogLevel.None

注意

若要完全禁用日志记录,请在 configureLogging 方法中指定 signalR.LogLevel.None

有关日志记录的详细信息,请参阅 SignalR 诊断文档

SignalR Java 客户端使用 SLF4J 库进行日志记录。 它是一个高级日志 API,允许库的用户通过引入特定的日志记录依赖项来选择自己的特定日志记录实现。 以下代码片段显示了如何将 java.util.logging 与 SignalR Java 客户端配合使用。

implementation 'org.slf4j:slf4j-jdk14:1.7.25'

如果没有在依赖项中配置日志记录,SLF4J 会加载默认的无操作记录器,并显示以下警告消息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

此错误可放心地忽略。

配置允许的传输

SignalR 使用的传输可以在 WithUrl 调用中配置(JavaScript 中的 withUrl)。 可以使用 HttpTransportType 值的按位 OR 来限制客户端仅使用指定的传输。 默认启用所有传输。

例如,要禁用“服务器发送的事件”传输,但允许 WebSocket 和长轮询连接,请执行以下操作:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", HttpTransportType.WebSockets | HttpTransportType.LongPolling)
    .Build();

在 JavaScript 客户端中,通过在提供给 withUrl 的 options 对象上设置 transport 字段来配置传输:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", { transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling })
    .build();

在此版本的 Java 客户端中,WebSocket 是唯一可用的传输。

在 Java 客户端中,通过 HttpHubConnectionBuilder 上的 withTransport 方法来选择传输。 Java 客户端默认使用 WebSocket 传输。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withTransport(TransportEnum.WEBSOCKETS)
    .build();

注意

SignalR Java 客户端尚不支持传输回退。

配置持有者身份验证

要随 SignalR 请求提供身份验证数据,请使用 AccessTokenProvider 选项(JavaScript 中的 accessTokenFactory)指定用于返回所需访问令牌的函数。 在 .NET 客户端中,此访问令牌作为HTTP“持有者身份验证”令牌传入(使用类型为 BearerAuthorization 头)。 在 JavaScript 客户端中,访问令牌充当持有者令牌,除了少数浏览器 API 会限制标头应用能力的情况(特别是在“服务器发送的事件”和 WebSocket 请求中)。 在这些情况下,访问令牌作为查询字符串值 access_token 提供。

在 .NET 客户端中,可以使用 WithUrl 中的选项委托来指定 AccessTokenProvider 选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.AccessTokenProvider = async () => {
            // Get and return the access token.
        };
    })
    .Build();

在 JavaScript 客户端中,通过在 withUrl 中的 options 对象上设置 accessTokenFactory 字段来配置访问令牌:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        accessTokenFactory: () => {
            // Get and return the access token.
            // This function can return a JavaScript Promise if asynchronous
            // logic is required to retrieve the access token.
        }
    })
    .build();

在 SignalR Java 客户端中,可以通过向 HttpHubConnectionBuilder 提供访问令牌工厂来配置持有者令牌,用于身份验证。 使用 withAccessTokenFactory 提供 RxJava Single<String>。 通过调用 Single.defer,你可以编写逻辑来为客户端生成访问令牌。

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
    .withAccessTokenProvider(Single.defer(() -> {
        // Your logic here.
        return Single.just("An Access Token");
    })).build();

配置超时和“保持活动状态”选项

HubConnection 对象本身提供了用于配置超时和保持活动状态行为的其他选项:

选项 默认值 说明
ServerTimeout 30 秒(30,000 毫秒) 服务器活动的超时。 如果服务器在此时间间隔内没有发送消息,则客户端会认为服务器已断开连接,并触发 Closed 事件(JavaScript 中为 onclose)。 此值必须足够大,以便在超时值间隔内能够从服务器发出 ping 消息并由客户端接收到。 要让 ping 能够到达,建议的值至少应是服务器 KeepAliveInterval 值的两倍。
HandshakeTimeout 15 秒 初始服务器握手的超时。 如果服务器在此时间间隔内没有发送握手响应,客户端将取消握手并触发 Closed 事件(JavaScript 中为 onclose)。 这是一个高级设置,只应在由于严重的网络延迟而发生握手超时错误时才考虑修改。 有关握手过程的更多详细信息,请参阅 SignalR 中心协议规范
KeepAliveInterval 15 秒 确定客户端发送 ping 消息时所在的间隔。 从客户端发送任何消息时,将重置计时器,重置到间隔的开始。 如果客户端没有在服务器上设置的 ClientTimeoutInterval 期间发送消息,服务器将认为客户端已断开连接。

在 .NET 客户端中,超时值指定为 TimeSpan 值。

配置其他选项

其他选项可以在 HubConnectionBuilder 上的 WithUrl(JavaScript 中的 withUrl)方法中配置,也可以在 Java 客户端的 HttpHubConnectionBuilder 上的各种配置 API 中配置:

.NET 选项 默认值 说明
AccessTokenProvider null 返回字符串的函数,该字符串在 HTTP 请求中作为持有者身份验证令牌提供。
SkipNegotiation false 将此设置为 true 以跳过协商步骤。 仅当 WebSocket 传输是唯一启用的传输时才受支持。 使用 Azure SignalR 服务时,无法启用此设置。
ClientCertificates 要发送的并用于对请求进行身份验证的 TLS 证书的集合。
Cookies 要随每个 HTTP 请求一起发送的 HTTP Cookie 的集合。
Credentials 要随每个 HTTP 请求一起发送的凭据。
CloseTimeout 5 秒 仅 WebSocket。 客户端在关闭后等待服务器确认关闭请求的最长时间。 如果服务器在此时间内未确认关闭,客户端将断开连接。
Headers 要随每个 HTTP 请求一起发送的其他 HTTP 标头的映射。
HttpMessageHandlerFactory null 一个委托,可用于配置或替换用于发送 HTTP 请求的 HttpMessageHandler。 不用于 WebSocket 连接。 此委托必须返回非 null 值,并接收默认值作为参数。 修改该默认值上的设置并将其返回,或返回一个新的 HttpMessageHandler 实例。 替换处理程序时,请确保从提供的处理程序中复制要保留的设置,否则配置的选项(例如 Cookie 和标头)将不会应用于新的处理程序。
Proxy null 发送 HTTP 请求时要使用的 HTTP 代理。
UseDefaultCredentials false 设置此布尔值以发送 HTTP 和 WebSockets 请求的默认凭据。 这能够支持使用 Windows 身份验证。
WebSocketConfiguration null 可用于配置其他 WebSocket 选项的委托。 接收可用于配置选项的 ClientWebSocketOptions 实例。
ApplicationMaxBufferSize 1 MB 在应用反压之前,客户端所缓冲的从服务器接收到的字节的最大数目。 增大此值可使客户端更快地接收更大的消息,而无需应用反压,但也会增加内存消耗。
TransportMaxBufferSize 1 MB 客户端在观察到反压之前所缓冲的由用户应用程序发送的字节的最大数目。 增大此值可使客户端更快地缓冲更大的消息,而不用等待反压,但也会增加内存消耗。

在 .NET 客户端中,可以通过提供给 WithUrl 的选项委托来修改这些选项:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/chathub", options => {
        options.Headers["Foo"] = "Bar";
        options.SkipNegotiation = true;
        options.Transports = HttpTransportType.WebSockets;
        options.Cookies.Add(new Cookie(/* ... */);
        options.ClientCertificates.Add(/* ... */);
    })
    .Build();

在 JavaScript 客户端中,可以在提供给 withUrl 的 JavaScript 对象中提供这些选项:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub", {
        // "Foo: Bar" will not be sent with WebSockets or Server-Sent Events requests
        headers: { "Foo": "Bar" },
        transport: signalR.HttpTransportType.LongPolling 
    })
    .build();

在 Java 客户端中,可以使用从 HubConnectionBuilder.create("HUB URL") 返回的 HttpHubConnectionBuilder 上的方法来配置这些选项

HubConnection hubConnection = HubConnectionBuilder.create("https://example.com/chathub")
        .withHeader("Foo", "Bar")
        .shouldSkipNegotiate(true)
        .withHandshakeResponseTimeout(30*1000)
        .build();

其他资源