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

如何用ASP.NET MVC和SignalR实现可实时更新的项列表?

嘿,你已经把基础的架子搭得差不多了!接下来咱们一步步把实时同步的增删功能落地,分后端和前端两部分来实现:

一、完善后端的SignalR Hub与数据管理

首先,咱们得给ItemHub添加核心方法,还要解决数据共享的问题——因为SignalR的Hub实例是每次请求都会创建的,所以得用一个静态集合来保存所有Item,确保所有连接的客户端都能看到同一份数据:

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.SignalR;

public class ItemHub : Hub
{
    // 用静态集合存储Item,保证所有Hub实例共享这份数据
    private static readonly ItemList _sharedItemList = new ItemList { Items = new List<Item>() };

    // 供客户端获取当前所有Item的方法
    public List<Item> GetCurrentItems()
    {
        return _sharedItemList.Items;
    }

    // 添加Item的方法,执行完通知所有客户端更新
    public void AddItem(string itemName)
    {
        if (!string.IsNullOrWhiteSpace(itemName))
        {
            var newItem = new Item { Name = itemName };
            _sharedItemList.Items.Add(newItem);
            // 给所有连接的客户端发送更新通知,传递最新的Item列表
            Clients.All.ItemsUpdated(_sharedItemList.Items);
        }
    }

    // 删除Item的方法,执行完通知所有客户端更新
    public void DeleteItem(string itemName)
    {
        var targetItem = _sharedItemList.Items.FirstOrDefault(i => 
            i.Name.Equals(itemName, System.StringComparison.OrdinalIgnoreCase));
        if (targetItem != null)
        {
            _sharedItemList.Items.Remove(targetItem);
            // 通知所有客户端刷新列表
            Clients.All.ItemsUpdated(_sharedItemList.Items);
        }
    }
}
二、配置SignalR路由

接下来要让ASP.NET知道SignalR的路由,如果你用的是带Owin的Startup类,就在Startup.cs里添加SignalR的映射:

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(YourAppName.Startup))]
namespace YourAppName
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 配置SignalR路由
            app.MapSignalR();
            // 保留你原本的MVC配置代码...
        }
    }
}

如果是旧版的MVC(用Global.asax),就在Application_Start方法里加一行:

RouteTable.Routes.MapHubs();
三、完善前端Items.cshtml视图

现在轮到前端了,咱们要引入SignalR的脚本,写页面结构,再实现和Hub的交互逻辑:

首先,在视图里引入必要的脚本(注意顺序:先jQuery,再SignalR核心,最后自动生成的Hub代理):

<script src="~/Scripts/jquery-3.6.0.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.4.3.min.js"></script>
<!-- 这个是SignalR自动生成的Hub代理脚本,路径固定为~/signalr/hubs -->
<script src="~/signalr/hubs"></script>

然后写页面的HTML结构,包含添加输入框、按钮和展示列表的区域:

<div class="container mt-4">
    <h2>实时同步Item列表</h2>
    <div class="mb-3">
        <input type="text" id="newItemName" class="form-control w-50 d-inline-block" placeholder="输入Item名称" />
        <button id="addItemBtn" class="btn btn-primary ms-2">添加Item</button>
    </div>
    <ul id="itemList" class="list-group w-50">
        <!-- 这里会动态生成列表项 -->
    </ul>
</div>

最后写JavaScript逻辑,实现连接Hub、获取初始数据、绑定增删事件,还有接收服务器的实时推送:

$(function () {
    // 创建ItemHub的代理对象
    var itemHub = $.connection.itemHub;

    // 定义客户端的方法,服务器会调用这个方法来推送更新后的列表
    itemHub.client.itemsUpdated = function (items) {
        renderItemList(items);
    };

    // 启动SignalR连接
    $.connection.hub.start().done(function () {
        console.log("已连接到SignalR Hub");
        
        // 连接成功后,先获取当前所有Item来初始化列表
        itemHub.server.getCurrentItems().done(function (items) {
            renderItemList(items);
        });

        // 绑定添加按钮的点击事件
        $('#addItemBtn').click(function () {
            var itemName = $('#newItemName').val().trim();
            if (itemName) {
                // 调用Hub的AddItem方法
                itemHub.server.addItem(itemName);
                $('#newItemName').val(''); // 清空输入框
            }
        });

        // 给动态生成的删除按钮绑定点击事件(用事件委托)
        $('#itemList').on('click', '.delete-btn', function () {
            var itemName = $(this).data('item-name');
            // 调用Hub的DeleteItem方法
            itemHub.server.deleteItem(itemName);
        });
    });

    // 渲染Item列表的辅助函数
    function renderItemList(items) {
        var $list = $('#itemList');
        $list.empty(); // 清空现有内容

        if (items.length === 0) {
            $list.append('<li class="list-group-item">暂无Item,添加一个试试吧!</li>');
            return;
        }

        // 遍历生成每个列表项,带删除按钮
        items.forEach(function (item) {
            var listItem = $('<li>').addClass('list-group-item d-flex justify-content-between align-items-center')
                .text(item.Name);
            
            var deleteBtn = $('<button>').addClass('btn btn-sm btn-danger delete-btn')
                .text('删除')
                .data('item-name', item.Name);
            
            listItem.append(deleteBtn);
            $list.append(listItem);
        });
    }
});
四、测试功能

现在启动你的ASP.NET MVC应用,打开多个浏览器窗口(或者用隐私模式开多个窗口),在任意一个窗口添加或删除Item,你会看到所有窗口的列表都会实时同步更新,完美实现了跨客户端的实时交互!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:35:19