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

寻求基于SignalR的.NET用户间推送通知方案及示例

Real-Time Table Update Notifications with SignalR in .NET (No Database Polling)

Hey there! SignalR is exactly the right tool for this scenario—you can get instant, real-time notifications without relying on slow database polling. Let’s break down a complete, workable approach with .NET-specific examples to get you up and running.

Core Approach

Instead of writing to a database and repeatedly checking for changes, we’ll trigger SignalR notifications the moment a user inserts a new table row. This keeps things fast and lightweight. Here’s the simple flow:

  1. A user submits a new table row to your backend.
  2. Your backend processes the row (save it to memory, a file, or a database—we just skip polling).
  3. Your backend uses SignalR to push an update to all other connected users immediately.
  4. Clients receive the notification and refresh their table view automatically.

Step 1: Set Up the SignalR Hub

First, create a SignalR Hub class—this acts as the central communication bridge between your server and clients.

using Microsoft.AspNetCore.SignalR;

public class TableUpdatesHub : Hub
{
    // We'll use server-side triggers to call this, but it can also be invoked from clients
    public async Task SendTableUpdate(string rowData)
    {
        // Send the update to every connected client except the one who triggered it
        await Clients.Others.SendAsync("ReceiveTableUpdate", rowData);
    }
}

Next, register SignalR in your Program.cs to enable the service and map the hub to a route:

var builder = WebApplication.CreateBuilder(args);

// Add SignalR to your service collection
builder.Services.AddSignalR();

// ... other service registrations (controllers, Razor Pages, etc.)

var app = builder.Build();

// ... middleware setup (static files, authentication, etc.)

// Map the hub to a URL clients can connect to
app.MapHub<TableUpdatesHub>("/tableUpdatesHub");

app.Run();

Step 2: Trigger Notifications from the Backend

When a user inserts a new row, inject IHubContext<TableUpdatesHub> into your controller/service to send the real-time update to other users.

Example: Controller Action for Adding Rows

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

[ApiController]
[Route("api/table")]
public class TableController : ControllerBase
{
    private readonly IHubContext<TableUpdatesHub> _hubContext;
    // Use a service to manage your table data (in-memory or persistent—no polling needed!)
    private readonly ITableDataService _tableDataService;

    public TableController(IHubContext<TableUpdatesHub> hubContext, ITableDataService tableDataService)
    {
        _hubContext = hubContext;
        _tableDataService = tableDataService;
    }

    [HttpPost("rows")]
    public async Task<IActionResult> AddRow([FromBody] TableRow newRow)
    {
        // 1. Save the new row to your data store
        await _tableDataService.AddRowAsync(newRow);

        // 2. Serialize the row data to send to clients
        var rowJson = System.Text.Json.JsonSerializer.Serialize(newRow);

        // 3. Notify all other connected users about the new row
        await _hubContext.Clients.Others.SendAsync("ReceiveTableUpdate", rowJson);

        return Ok(newRow);
    }
}

// DTO for your table row
public class TableRow
{
    public int Id { get; set; }
    public string Column1 { get; set; } = string.Empty;
    public string Column2 { get; set; } = string.Empty;
}

Step 3: Client-Side Integration

Connect your frontend to the SignalR hub to receive and display updates. Below are examples for two common .NET frontend scenarios:

Option 1: Blazor (Server or WebAssembly)

In a Blazor component (e.g., SharedTable.razor):

@page "/shared-table"
@inject HubConnection HubConnection
@inject HttpClient Http
@implements IAsyncDisposable

<h3>Shared Table</h3>
<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Column 1</th>
            <th>Column 2</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var row in TableRows)
        {
            <tr>
                <td>@row.Id</td>
                <td>@row.Column1</td>
                <td>@row.Column2</td>
            </tr>
        }
    </tbody>
</table>

@code {
    private List<TableRow> TableRows = new();

    protected override async Task OnInitializedAsync()
    {
        // Initialize the hub connection
        HubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/tableUpdatesHub"))
            .Build();

        // Listen for incoming table updates
        HubConnection.On<string>("ReceiveTableUpdate", async (rowJson) =>
        {
            var newRow = System.Text.Json.JsonSerializer.Deserialize<TableRow>(rowJson);
            if (newRow != null)
            {
                TableRows.Add(newRow);
                StateHasChanged(); // Refresh the UI
            }
        });

        await HubConnection.StartAsync();

        // Load initial table data from your API
        TableRows = await Http.GetFromJsonAsync<List<TableRow>>("/api/table/rows") ?? new();
    }

    public async ValueTask DisposeAsync()
    {
        if (HubConnection != null)
        {
            await HubConnection.DisposeAsync();
        }
    }
}

Don’t forget to register the HubConnection in Program.cs for Blazor:

builder.Services.AddScoped<HubConnection>(sp =>
{
    var navigationManager = sp.GetRequiredService<NavigationManager>();
    return new HubConnectionBuilder()
        .WithUrl(navigationManager.ToAbsoluteUri("/tableUpdatesHub"))
        .Build();
});

Option 2: Razor Pages/MVC (JavaScript)

In your Razor Page or View, add this JavaScript to connect to the hub and update the table:

<script src="~/lib/signalr/dist/browser/signalr.js"></script>
<script>
    // Initialize the SignalR connection
    const connection = new signalR.HubConnectionBuilder()
        .withUrl("/tableUpdatesHub")
        .build();

    // Listen for new row updates
    connection.on("ReceiveTableUpdate", function (rowJson) {
        const newRow = JSON.parse(rowJson);
        // Add the new row to the table DOM
        const tableBody = document.getElementById("table-body");
        const rowElement = document.createElement("tr");
        rowElement.innerHTML = `
            <td>${newRow.id}</td>
            <td>${newRow.column1}</td>
            <td>${newRow.column2}</td>
        `;
        tableBody.appendChild(rowElement);
    });

    // Start the connection
    connection.start().catch(function (err) {
        return console.error(err.toString());
    });
</script>

<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Column 1</th>
            <th>Column 2</th>
        </tr>
    </thead>
    <tbody id="table-body">
        <!-- Initial rows loaded from server -->
    </tbody>
</table>

Key Notes

  • No Database Polling: We push updates directly from the server when a row is inserted—no repeated database checks to slow things down.
  • Targeted Notifications: Clients.Others ensures the user who added the row doesn’t get a duplicate update (use Clients.All if you want everyone, including the sender, to see the update).
  • Scalability: If you need to scale beyond a single server, add a SignalR backplane (like Redis or Azure Service Bus) to sync messages across servers. For small to medium apps, the basic setup works perfectly.

内容的提问来源于stack exchange,提问作者Alexandra Damaschin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:05:21