You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中为所有用户实现结合SignalR的Toast推送通知?

实现ASP.NET Core + SignalR + Windows Toast通知完整方案

一、确认SignalR后端基础配置(已完成可跳过)

  • 安装NuGet包:Microsoft.AspNetCore.SignalR
  • 在Program.cs中注册SignalR服务并配置中间件:
builder.Services.AddSignalR();
// 跨域配置(前端独立部署时需要)
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowSignalR", policy =>
    {
        policy.AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials()
              .WithOrigins("你的前端域名");
    });
});

// 中间件顺序不能错
app.UseCors("AllowSignalR");
app.MapHub<NotificationHub>("/notificationHub");
  • 创建SignalR Hub类:
public class NotificationHub : Hub
{
    // 向所有连接客户端广播消息
    public async Task BroadcastNotification(string title, string content)
    {
        await Clients.All.SendAsync("ReceiveNotification", title, content);
    }
}

二、监听数据库新增事件并触发推送

推荐用EF Core拦截SaveChanges的方式,代码可控性强:

public class AppDbContext : DbContext
{
    private readonly IHubContext<NotificationHub> _hubContext;

    public AppDbContext(DbContextOptions<AppDbContext> options, IHubContext<NotificationHub> hubContext)
        : base(options)
    {
        _hubContext = hubContext;
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        // 捕获新增的实体
        var addedEntities = ChangeTracker.Entries()
            .Where(e => e.State == EntityState.Added)
            .Select(e => e.Entity);

        int saveResult = await base.SaveChangesAsync(cancellationToken);

        // 有新增数据时触发推送
        if (addedEntities.Any())
        {
            // 可根据实体类型自定义通知内容
            await _hubContext.Clients.All.SendAsync(
                "ReceiveNotification", 
                "系统通知", 
                "数据库新增了一条新记录"
            );
        }

        return saveResult;
    }
}

三、前端集成SignalR并实现Windows Toast通知

这是核心环节,重点处理浏览器通知权限和消息接收逻辑:

1. 引入SignalR客户端

  • Razor Pages/MVC项目:用LibMan引入@microsoft/signalr客户端脚本
  • Vue/React等SPA:执行npm install @microsoft/signalr安装包

2. 前端核心代码

// 初始化SignalR连接
const connection = new signalR.HubConnectionBuilder()
    .withUrl("/notificationHub")
    .withAutomaticReconnect()
    .build();

// 请求浏览器通知权限
async function getNotificationPermission() {
    if (!("Notification" in window)) {
        alert("当前浏览器不支持桌面通知");
        return false;
    }
    const permission = await Notification.requestPermission();
    return permission === "granted";
}

// 监听SignalR推送的消息
connection.on("ReceiveNotification", async (title, content) => {
    const hasPermission = await getNotificationPermission();
    if (hasPermission) {
        // 触发Windows系统级Toast通知
        new Notification(title, {
            body: content,
            icon: "/images/notification-icon.png", // 可选:自定义通知图标
            requireInteraction: false // 是否保持通知直到用户操作
        });
    }
});

// 启动连接并处理重连
async function startSignalRConnection() {
    try {
        await connection.start();
        console.log("SignalR连接成功");
    } catch (err) {
        console.error("SignalR连接失败:", err);
        setTimeout(startSignalRConnection, 5000); // 5秒后重试
    }
}

// 页面加载时启动连接
window.addEventListener("load", startSignalRConnection);

关键注意事项

  • HTTPS要求:浏览器的Notification API仅支持HTTPS环境(localhost开发环境例外),生产环境必须部署HTTPS。
  • 权限持久化:用户授权一次后,浏览器会保存权限设置,除非用户手动在浏览器设置中修改。
  • 通知样式:Windows系统的Toast样式由浏览器和系统设置决定,基础通知用上述代码即可满足需求,如需更复杂样式可结合Service Worker实现。

四、测试验证

  1. 启动项目,打开多个浏览器窗口/标签页
  2. 通过接口或页面操作向数据库新增数据
  3. 检查所有打开的页面是否收到Windows Toast通知

内容的提问来源于stack exchange,提问作者Nidal HAMID

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:35:22