ASP.NET Core SignalR 客户端和服务端高级配置总结

一、客户端和服务端超时配置

SignalR 提供了一些选项,用于配置连接的超时和断开逻辑。

1. 服务器端配置

在服务端,可以通过 AddSignalR 配置超时参数:

services.AddSignalR(options =>
{
    // 设置客户端超时时间(默认30秒)
    options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);

    // 设置服务器超时时间,客户端未发送消息的最大间隔时间(默认15秒)
    options.KeepAliveInterval = TimeSpan.FromSeconds(10);

    // 设置连接最大寿命时间(可选)
    options.HandshakeTimeout = TimeSpan.FromSeconds(15);
});
  • ClientTimeoutInterval: 如果客户端在指定时间内未响应,则服务器认为客户端已断开。
  • KeepAliveInterval: 服务器发送心跳包的间隔时间。
  • HandshakeTimeout: 客户端在此时间内未完成握手,连接将关闭。

2. 客户端配置

在客户端,可以设置连接重试逻辑:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chatHub")
    .withAutomaticReconnect({
        nextRetryDelayInMillisecondsretryContext => {
            return Math.min(retryContext.elapsedMilliseconds + 1000, 10000);
        }
    })
    .build();

connection.keepAliveIntervalInMilliseconds = 15000; // 默认15000ms
connection.serverTimeoutInMilliseconds = 60000; // 默认30000ms

connection.start().catch(err => console.error(err));
  • keepAliveIntervalInMilliseconds: 客户端发送心跳包的间隔时间。
  • serverTimeoutInMilliseconds: 如果在指定时间内未收到服务器消息,客户端认为连接已断开。

二、心跳机制

心跳是 SignalR 中用于检测连接状态的重要机制。

  1. 服务器心跳

    • 通过 KeepAliveInterval 控制。
    • 服务器在指定时间间隔内向客户端发送心跳包,客户端响应后保持连接。
  2. 客户端心跳

    • 通过 keepAliveIntervalInMilliseconds 控制。
    • 客户端向服务器发送心跳,确保连接持续。

三、传输协商机制

SignalR 会自动协商最佳传输协议,但开发者可以手动指定。

1. 支持的协议顺序

  • WebSocket
  • Server-Sent Events (SSE)
  • Long Polling

2. 手动指定协议

在客户端可以通过 HubConnectionBuilder 指定:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chatHub")
    .withHubProtocol(new signalR.JsonHubProtocol())
    .withTransport(signalR.HttpTransportType.WebSockets) // 仅使用 WebSocket
    .build();

四、Redis 支持

在分布式系统中,SignalR 可以使用 Redis 实现多服务器之间的消息广播。

1. 安装 Redis 包

Install-Package Microsoft.AspNetCore.SignalR.StackExchangeRedis

2. 配置 Redis

在服务端,通过 AddStackExchangeRedis 添加 Redis 支持:

services.AddSignalR().AddStackExchangeRedis("localhost:6379", options =>
{
    options.Configuration.ChannelPrefix = "SignalR:";
});
  • ChannelPrefix: 用于区分不同 SignalR 应用的 Redis 通道前缀。

3. 部署注意事项

  • 确保所有服务器共享相同的 Redis 实例。
  • 确保 Redis 配置的最大消息长度足够大,以支持大消息广播。

五、综合示例

服务端代码

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSignalR(options =>
{
    options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
    options.KeepAliveInterval = TimeSpan.FromSeconds(10);
    options.HandshakeTimeout = TimeSpan.FromSeconds(15);
})
.AddStackExchangeRedis("localhost:6379", options =>
{
    options.Configuration.ChannelPrefix = "MyAppSignalR:";
});

var app = builder.Build();

app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<ChatHub>("/chatHub");
});

app.Run();

客户端代码

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chatHub")
    .withAutomaticReconnect()
    .withTransport(signalR.HttpTransportType.WebSockets)
    .build();

connection.on("ReceiveMessage", (user, message) => {
    console.log(`${user}${message}`);
});

connection.start()
    .then(() => console.log("Connected"))
    .catch(err => console.error("Connection failed", err));

六、总结

  1. 超时配置和心跳机制:确保连接稳定性,减少误判断开。
  2. 传输协议协商:优化传输性能,优先使用 WebSocket。
  3. Redis 支持:实现分布式消息广播,适用于大规模部署。

通过以上配置,SignalR 可实现高效、可靠的实时通信功能,同时在分布式环境中提供强大的扩展能力。

posted @   跟着阿笨一起玩.NET  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-02-04 SQL Server数据库高级进阶之事务实战演练
2021-02-04 C#如何正确运用异步编程技术
2021-02-04 SQL Server数据库高级进阶之锁实战演练
2020-02-04 .NET Core基于SQL Server数据库主从同步实现读写分离实战演练
2013-02-04 将要被社会淘汰的8种人
点击右上角即可分享
微信分享提示