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

如何让SignalR invoke恢复代码优先于消息处理器执行?

解决方案

要让invoke调用完成后的恢复代码优先于消息处理器执行,核心思路是暂时缓存推送的消息,待invoke恢复逻辑执行完毕后再处理缓存的消息。具体实现步骤如下:

1. 新增状态标记与消息缓存队列

在你的类中添加两个变量,用于跟踪invoke状态和缓存待处理消息:

// 标记是否有invoke请求处于等待状态
#isInvokePending = false;
// 缓存待处理的GameDataUpdate消息
#pendingGameUpdates: GameDataUpdate[] = [];

2. 修改消息处理器逻辑

原消息处理器不再直接处理消息,而是根据#isInvokePending状态决定缓存或立即处理:

this.connection.on("GameDataUpdatedV1", async (evt: GameDataUpdatedEvent) => {
    if (this.#isInvokePending) {
        // 若有invoke在等待,先缓存消息
        this.#pendingGameUpdates.push(evt.updateData);
    } else {
        // 无invoke等待时,正常处理消息
        await this.#handleGameDataUpdate(evt.updateData);
    }
});

3. 调整invoke调用流程

在调用invoke前标记状态,调用完成后先执行恢复代码,再批量处理缓存的消息:

console.log("About to invoke...");
this.#isInvokePending = true;
try {
    await this.connection.invoke("TestInvoke", { testData: 123 });
    // 优先执行invoke恢复逻辑
    console.log("Resumed from invoke.");
} finally {
    this.#isInvokePending = false;
    // 批量处理缓存的消息
    for (const update of this.#pendingGameUpdates) {
        await this.#handleGameDataUpdate(update);
    }
    // 清空缓存队列
    this.#pendingGameUpdates = [];
}

原理说明

SignalR的消息推送处理器和invoke的回调逻辑都运行在JavaScript的同一个事件循环队列中。当invoke处于等待状态时,服务器推送的消息会不断进入事件队列并被依次执行,导致处理器输出先于invoke恢复代码。通过手动缓存消息并延迟处理,我们可以确保invoke完成后的逻辑优先执行,再统一处理期间积累的推送消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:31:02