使用 SignalR 实现实时应用(聊天 / 通知)完整指南(ASP.NET Core 实战)

什么是 SignalR?

在传统 Web 应用中,客户端与服务器的通信通常依赖请求-响应模型,实时性较差。而 SignalR 是 ASP.NET Core 提供的一套实时通信库,可以让服务器主动向客户端推送消息,实现即时更新。它的核心能力是:

  • 双向通信(客户端 ↔ 服务端)
  • 自动选择最佳传输协议(WebSockets / SSE / Long Polling)
  • 支持浏览器、移动端等多端实时同步

简单来说,SignalR 就像一个持续连接的通道,让服务器可以随时通知客户端,而不需要刷新页面。

SignalR 的典型应用场景

SignalR 非常适合以下实时场景:

  • 在线聊天系统(类似微信 Web / Slack)
  • 实时通知(消息提醒、系统公告)
  • 实时数据面板(监控、股票、IoT)
  • 多人协作(白板、编辑器)
  • 游戏同步(多人互动)

其中最常见的两个就是:聊天系统和通知系统。

SignalR 核心架构

SignalR 的核心由三个部分组成:

1. Hub(核心通信中心)

Hub 是服务端的中枢,负责处理客户端请求并广播消息。

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

说明:

  • 客户端调用 SendMessage
  • Hub 再调用客户端方法 ReceiveMessage
  • 实现广播

本质:Hub = WebSocket 控制器

2. Client(客户端)

前端通过 JavaScript / .NET / 其他语言连接 Hub:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chatHub")
    .build();

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

connection.start();

3. Transport(传输机制)

SignalR 自动选择最佳通信方式:

优先级:

  1. WebSockets(性能最好)
  2. Server-Sent Events
  3. Long Polling

开发者无需关心底层细节。

实战:实现一个实时聊天系统

步骤 1:创建 ASP.NET Core 项目

dotnet new webapp

安装依赖:

dotnet add package Microsoft.AspNetCore.SignalR

步骤 2:注册 SignalR

builder.Services.AddSignalR();

app.MapHub<ChatHub>("/chatHub");

步骤 3:前端页面

<input id="user" />
<input id="message" />
<button onclick="send()">发送</button>

<script>
function send() {
    connection.invoke("SendMessage",
        document.getElementById("user").value,
        document.getElementById("message").value);
}
</script>

步骤 4:运行效果

打开多个浏览器窗口:

  • 任意一端发送消息
  • 所有客户端实时收到

SignalR 会把消息广播给所有连接用户

实现实时通知系统

聊天是广播,而通知通常是定向发送。

1. 发送给指定用户

await Clients.User(userId)
    .SendAsync("ReceiveNotification", "你有新消息");

2. 使用 Group(分组通知)

await Groups.AddToGroupAsync(Context.ConnectionId, "admin");

await Clients.Group("admin")
    .SendAsync("ReceiveMessage", "系统通知");

适用于:

  • 部门通知
  • 群聊
  • 权限控制

3. 离线消息处理(关键点)

SignalR 默认不存储消息,只负责实时推送:

  • 用户不在线 → 收不到
  • 页面刷新 → 状态丢失

解决方案:

  • 数据库存储消息
  • 登录后补发

进阶:SignalR 高级用法

1. 强类型 Hub

public interface IChatClient
{
    Task ReceiveMessage(string user, string message);
}

public class ChatHub : Hub<IChatClient>
{
}

优点:类型安全、可维护性更高

2. 扩展(Scale Out)

SignalR 支持分布式扩展:

  • Redis(常用)
  • Azure SignalR Service
  • Message Queue

适用于高并发聊天系统

3. 鉴权与安全

常见做法:

  • JWT + SignalR
  • 用户ID绑定连接
  • 限制Hub访问权限

SignalR 优缺点分析

优点

  • 简单易用(封装底层通信)
  • 实时性强
  • 支持多协议自动降级
  • 与 ASP.NET 生态高度集成

缺点

  • 不适合离线消息(需自己实现)
  • 高并发需额外扩展(Redis / Azure)
  • 长连接占资源

总结

SignalR 是构建实时 Web 应用的核心技术之一,尤其适合聊天系统、实时通知、数据推送。通过 Hub + Client 的模式,可以快速实现双向通信,让 Web 应用从请求驱动升级为事件驱动。如果你正在做 .NET 项目,SignalR 几乎是实现实时功能的首选方案。

评论