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

能否不使用Knockout使用SignalR?需实现页面告警更新及标签页闪烁功能

当然可以不用Knockout来使用SignalR!

完全没问题,SignalR本身和Knockout没有绑定关系——它只是一个专注于实时通信的库,你用原生JS、任意前端框架甚至不用框架,都能轻松实现你要的功能。下面一步步给你拆解具体实现方案:

一、基础SignalR客户端配置(原生JS)

首先你需要引入SignalR的客户端脚本(如果是ASP.NET Core环境,通常用@microsoft/signalr包),然后建立与服务端Hub的连接:

// 初始化SignalR连接
const connection = new signalR.HubConnectionBuilder()
    .withUrl("/alarmHub") // 替换成你自己的Hub路由地址
    .withAutomaticReconnect() // 可选:断连后自动尝试重连
    .build();

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

// 启动连接
startSignalRConnection();

二、实现告警更新:两种方案适配你的需求

根据你“无需实时,但更新间隔至少10秒”的要求,这里提供两种实用方案:

方案1:客户端定时主动拉取

如果不想用实时推送,客户端可以每隔10秒主动调用服务端的Hub方法,获取这段时间内的新告警:

// 每隔10秒拉取一次新告警
setInterval(async () => {
    // 确保连接处于活跃状态再发起请求
    if (connection.state === signalR.HubConnectionState.Connected) {
        const newAlarms = await connection.invoke("GetLatestAlarms"); // 对应服务端的GetLatestAlarms方法
        if (newAlarms.length > 0) {
            updateAlarmDisplay(newAlarms); // 更新页面上的告警展示
            checkIfNeedBlink(); // 检查是否需要触发标签页闪烁
        }
    }
}, 10000);

方案2:服务端定时推送(更高效)

让服务端每隔10秒主动收集新告警,推送给所有在线客户端,客户端只需监听对应的推送事件即可:

// 监听服务端推送的新告警事件
connection.on("ReceiveNewAlarms", (newAlarms) => {
    updateAlarmDisplay(newAlarms);
    checkIfNeedBlink();
});

服务端的Hub里可以用定时任务(比如Timer或后台托管服务),每隔10秒筛选出新告警,再通过Clients.All.SendAsync("ReceiveNewAlarms", newAlarms)推送给所有客户端。

三、实现标签页闪烁提示

要判断用户是否在当前页面,需要用到浏览器的visibilitychange API,再通过切换文档标题实现闪烁效果:

let isPageActive = true;
let blinkTimer = null;

// 监听页面可见性变化
document.addEventListener("visibilitychange", () => {
    isPageActive = !document.hidden;
    // 用户切回页面时,停止闪烁并恢复原标题
    if (isPageActive && blinkTimer) {
        clearInterval(blinkTimer);
        document.title = "你的页面默认标题"; // 替换成你页面的原始标题
        blinkTimer = null;
    }
});

// 检查是否需要触发闪烁
function checkIfNeedBlink() {
    if (!isPageActive) {
        startTitleBlink();
    }
}

// 启动标题闪烁逻辑
function startTitleBlink() {
    if (blinkTimer) return; // 避免重复开启定时器
    const originalTitle = document.title;
    const alertTitle = "[有新告警!]";
    let isAlertState = false;

    blinkTimer = setInterval(() => {
        document.title = isAlertState ? originalTitle : alertTitle;
        isAlertState = !isAlertState;
    }, 1000); // 每秒切换一次标题,实现闪烁效果
}

// 示例:更新页面告警展示的函数
function updateAlarmDisplay(alarms) {
    const alarmContainer = document.getElementById("alarm-list"); // 页面上的告警列表容器
    alarms.forEach(alarm => {
        const alarmItem = document.createElement("div");
        alarmItem.className = "alarm-item";
        alarmItem.innerHTML = `<span class="alarm-time">${alarm.CreateTime}</span> <span class="alarm-content">${alarm.Content}</span>`;
        alarmContainer.prepend(alarmItem); // 新告警放在列表最上方
    });
}

四、几个注意点

  • 记得处理连接异常:比如SignalR断开时,暂停轮询或等待重连完成后再恢复逻辑。
  • 如果是跨域场景,要在服务端配置好SignalR的跨域规则。
  • 标签页闪烁不要设置太频繁,1秒切换一次的频率既醒目又不会过度打扰用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:32:30