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

ASP.NET Core中如何在多个cshtml文件复用SignalR连接

ASP.NET Core中复用SignalR连接的解决方案

问题场景

在ASP.NET Core项目的_Layout.cshtml脚本块中创建并启动了SignalR连接,IndexNew.cshtml引用该布局页,希望复用_Layout中已创建的连接以避免重复实例化。曾尝试将连接代码抽成独立JS文件,但导入到两个页面仍会创建两个连接,需解决连接复用问题。

解决步骤

1. 将连接实例暴露到全局作用域

原代码中const connection是$(document).ready内部的局部变量,子页面无法访问。需将其挂载到window全局对象,让所有引用该布局的页面都能获取到同一个实例。

修改后的_Layout.cshtml脚本部分:

<script>
    $(document).ready(function () {
        setInterval(makeAjaxCall, 600000)

        // 将连接挂载到window全局对象,确保子页面可访问
        window.auctionHubConnection = new signalR.HubConnectionBuilder()
            .withUrl("/auctionHub")
            .build();

        window.auctionHubConnection.start().then(function () {
            console.log("Bağlantı başlatıldı.");
        }).catch(function (err) {
            console.error(err);
        });

        window.auctionHubConnection.on("connected", function () {
            console.log("Bağlandı");
        });

        window.auctionHubConnection.on("ReceiveBidLayout", function (acutionId, propertyCode) {
            $("#auctionId").text(acutionId);
            $("#propertyCode").text(propertyCode);
        });
    });
</script>

2. 子页面复用全局连接并注册事件

子页面IndexNew.cshtml直接使用全局的连接实例,同时需处理连接可能未完成初始化的情况,确保事件注册在连接启动后执行。

修改后的IndexNew.cshtml脚本部分:

<script>
    var input = document.getElementById("inputNumber");
    var button = document.getElementById("buttonNumber");
    var validate_error = document.querySelector(".validate");

    var maxBid = 0;

    $(document).ready(function () {
        // 复用全局连接实例
        if (window.auctionHubConnection) {
            // 根据连接状态决定何时注册事件
            if (window.auctionHubConnection.state === signalR.HubConnectionState.Connected) {
                registerHubEvents();
            } else {
                // 若连接未启动,等待启动完成后注册事件
                window.auctionHubConnection.start()
                    .then(registerHubEvents)
                    .catch(err => console.error(err));
            }
        }

        function registerHubEvents() {
            window.auctionHubConnection.on("connected", function () {
                console.log("Bağlandı");
            });

            // 修正原代码的语法错误:括号位置错误
            window.auctionHubConnection.on("addAuctionMember", function (count) {
                $("#lblTotalMember").text(count);
            });

            window.auctionHubConnection.on("ReceiveBid", function (result) {
                $("#lblTotalMember").text(result.totalMember);
                $("#labelTotalBid").text(result.totalBidAmount);
                $("#lblMaxBid").text(result.lastBid);
                document.getElementById("hMaxBid").innerHTML = result.lastBid;
                maxBid = result.lastBid;
            });
        }
    });
</script>

3. 可选优化:封装为单例模块(更规范的写法)

如果项目中有多个页面需要复用连接,可将连接逻辑封装成单例模块,确保全局仅创建一次连接:

新建auctionHub.js文件:

(function(window) {
    let connectionInstance;

    function getAuctionHubConnection() {
        if (!connectionInstance) {
            connectionInstance = new signalR.HubConnectionBuilder()
                .withUrl("/auctionHub")
                .build();

            connectionInstance.start().then(() => {
                console.log("Bağlantı başlatıldı.");
            }).catch(err => console.error(err));

            // 布局页需要的事件监听可放在这里
            connectionInstance.on("connected", () => {
                console.log("Bağlandı");
            });

            connectionInstance.on("ReceiveBidLayout", (acutionId, propertyCode) => {
                $("#auctionId").text(acutionId);
                $("#propertyCode").text(propertyCode);
            });
        }
        return connectionInstance;
    }

    window.AuctionHub = {
        getConnection: getAuctionHubConnection
    };
})(window);

在_Layout.cshtml中引入该JS文件:

<script src="~/js/auctionHub.js"></script>

子页面IndexNew.cshtml中使用:

$(document).ready(function () {
    const connection = window.AuctionHub.getConnection();
    
    // 注册子页面专属事件
    connection.on("ReceiveBid", function (result) {
        // 事件逻辑
    });
});

注意事项

  • 避免使用过于通用的全局变量名(如connection),建议用独特命名(如auctionHubConnection)防止命名冲突
  • 子页面需处理连接未初始化的边界情况,避免控制台报错
  • 注意修正原代码中的语法错误(如addAuctionMember事件的括号位置错误)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 09:57:40