SignalR 中心与连接
创建 SignalR 中心,在 ASP.NET Core 中映射它,并从 JavaScript 和 .NET 客户端建立 WebSocket 连接。
SignalR 中心与连接 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
什么是 SignalR?
SignalR 是一个 ASP.NET Core 库,用于在服务器与客户端之间实现实时双向通信。它会根据双方支持的功能,自动选择最佳传输方式:WebSockets、服务器发送事件或长轮询。
设置 SignalR
将 SignalR 添加到服务中,并映射一个中心端点。中心是负责处理客户端连接和方法调用的类。
builder.Services.AddSignalR();
var app = builder.Build();
app.UseCors("AllowAll");
app.MapHub<ChatHub>("/hubs/chat");
app.Run();创建中心
继承 Hub。中心方法由客户端调用。Context 属性提供连接信息,而 Clients 允许您发送消息。
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// Broadcast to ALL connected clients
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public override async Task OnConnectedAsync()
{
await Clients.Caller.SendAsync("Welcome",
$"Connected as {Context.ConnectionId}");
await base.OnConnectedAsync();
}
}JavaScript Client
官方 SignalR JavaScript client 会构建连接、注册事件处理程序并启动连接。中心上定义的方法可以从 JavaScript 调用。
// npm install @microsoft/signalr
import * as signalR from "@microsoft/signalr";
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect()
.build();
connection.on("ReceiveMessage", (user, message) => {
console.log(`${user}: ${message}`);
});
await connection.start();
await connection.invoke("SendMessage", "Alice", "Hello!");.NET SignalR Client
.NET client 的工作方式相同,适用于服务之间的实时通信或桌面、移动应用。
// dotnet add package Microsoft.AspNetCore.SignalR.Client
var connection = new HubConnectionBuilder()
.WithUrl("https://myapp.com/hubs/chat")
.WithAutomaticReconnect()
.Build();
connection.On<string, string>("ReceiveMessage", (user, msg) =>
Console.WriteLine($"{user}: {msg}"));
await connection.StartAsync();
await connection.InvokeAsync("SendMessage", "Bot", "Connected!");向特定 Clients 发送消息
Clients 属性提供了用于定位特定连接、调用方或除指定对象之外的所有已连接客户端的方法。
// To the caller only
await Clients.Caller.SendAsync("YouSaid", message);
// To a specific connection
await Clients.Client(connectionId).SendAsync("PrivateMsg", msg);
// To all except caller
await Clients.Others.SendAsync("ReceiveMessage", user, message);
// To multiple specific connections
await Clients.Clients(new[] { id1, id2 })
.SendAsync("DirectMsg", msg);中心上下文:从中心外部发送消息
将 IHubContext<T> 注入服务或后台工作程序,即可从中心类外部发送消息,这对于服务器发起的推送至关重要。
public class NotificationService
{
private readonly IHubContext<ChatHub> _hub;
public NotificationService(IHubContext<ChatHub> hub) => _hub = hub;
public async Task BroadcastAlertAsync(string alert)
{
// Send to all clients from a background service
await _hub.Clients.All.SendAsync("SystemAlert", alert);
}
}连接生命周期事件
重写 OnConnectedAsync 和 OnDisconnectedAsync,以跟踪连接、维护状态或清理资源。
public override async Task OnConnectedAsync()
{
_connections.TryAdd(Context.ConnectionId, GetUserName());
await Clients.All.SendAsync("UserJoined", GetUserName());
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? ex)
{
_connections.TryRemove(Context.ConnectionId, out var user);
await Clients.All.SendAsync("UserLeft", user);
await base.OnDisconnectedAsync(ex);
}
private string GetUserName() =>
Context.User?.Identity?.Name ?? Context.ConnectionId;自动重新连接
在 client 上启用自动重新连接,以便妥善处理短暂的断开连接。您可以自定义重试延迟。
// JavaScript client
const conn = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect([0, 2000, 5000, 10000, 30000]) // retry delays in ms
.build();
conn.onreconnecting(err => console.warn("Reconnecting...", err));
conn.onreconnected(id => console.log("Reconnected:", id));
conn.onclose(err => console.error("Disconnected:", err));使用 SignalR 进行身份验证
SignalR 遵循 ASP.NET Core 身份验证中间件。将 [Authorize] 添加到中心类,或使用支持查询字符串令牌的 JWT handler(WebSocket 身份验证所必需)。
[Authorize]
public class PrivateHub : Hub
{
public Task SendMessage(string msg)
{
var user = Context.User!.Identity!.Name;
return Clients.All.SendAsync("Msg", user, msg);
}
}
// JWT via query string (WebSocket requirement):
builder.Services.AddAuthentication().AddJwtBearer(opt =>
{
opt.Events = new JwtBearerEvents
{
OnMessageReceived = ctx =>
{
var token = ctx.Request.Query["access_token"];
if (!string.IsNullOrEmpty(token))
ctx.Token = token;
return Task.CompletedTask;
}
};
});快速检查
如何从后台服务(中心类外部)发送 SignalR 消息?
回顾:SignalR 中心与连接
要点:
- SignalR 会自动选择最佳传输方式(WebSockets、SSE、长轮询)
- 中心方法可由客户端调用;
Clients.*用于定位特定接收者 - 注入
IHubContext<T>,即可从中心外部推送消息 - 重写
OnConnectedAsync/OnDisconnectedAsync以管理生命周期 - 使用
withAutomaticReconnect()构建具有弹性的 client 连接 - WebSocket 连接必须通过查询字符串使用 JWT 身份验证
用 AI 导师学习 C# — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 93
- 课程
- 346
常见问题解答
「SignalR 中心与连接」课时是免费的吗?
是的 — 「SignalR 中心与连接」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「SignalR 中心与连接」这节课中我会学到什么?
创建 SignalR 中心,在 ASP.NET Core 中映射它,并从 JavaScript 和 .NET 客户端建立 WebSocket 连接。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「SignalR 中心与连接」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- SignalR 中心与连接
- 组、用户与连接管理
- 强类型中心
- 使用 Redis 后端扩展