我们有一个signalR hub和JavaScript客户端。在客户端,我们称之为" start"集线器代理上的方法,发送到服务器。服务器在准备就绪时将几条消息推送到客户端,然后完成。我们希望看到序列" Invoking ... event ... event ... event ... Invoked
",但我们看到的往往是" Invoking ... event ... event ... Invoked ... event
"。
这很糟糕,因为在完成集线器调用之后发生的JavaScript代码不是可靠的地方,可以停止收听并生成最终摘要 - 如果我们在这里停止收听消息,那么我们很有可能失去数据和显示" 95%完成"。
即
errorsHub.invoke('start', requestData)
.done(function() {
// this will lose data
errorsHub.off('errorsUpdate');
showFinalSummary();
});
如果没有" off",控制台调试消息如下所示:
[14:36:23 GMT+0100 (GMT Standard Time)] SignalR: Invoking errorshub.start
[14:36:23 GMT+0100 (GMT Standard Time)] SignalR: Triggering client hub event 'errorsUpdate' on hub 'ErrorsHub'.
...
[14:36:24 GMT+0100 (GMT Standard Time)] SignalR: Invoked errorshub.start
[14:36:24 GMT+0100 (GMT Standard Time)] SignalR: Triggering client hub event 'errorsUpdate' on hub 'ErrorsHub'.
有时最后一次更新是在"调用"之后不久发生的,但最长可能会在6秒之后。 通常我们会丢失最后一次更新,有时我们会丢失两次。
Firefox中的问题比Chrome中更常见。由于服务器是IIS 7.5,我们默认为长轮询传输
如果"已调用,则调用已完成"消息是在与更新相同的管道上发送的,它怎么能超过管道中的最后一次更新?在服务器上,当我们呼叫destination.errorsUpdate(someData)
时,这是发送和确认,发送还是排队等待发送?如果它刚刚排队,是否有办法从服务器刷新连接,以确保已发送上次更新?
我们会在JavaScript客户端中完全忽略invoke(...).done
并检查更新是否有特殊的消息信号完成?
答案 0 :(得分:1)
当服务器端方法返回时调用done()
处理程序,但它不保证服务器端方法触发的任何异步操作都已完成(调用客户端集线器方法不会发生在处理服务器端集线器方法的同一个任务,消息只是排队,然后由消息总线处理。)
我不确定你要做什么,所以提供有针对性的建议很困难;一个简单的解决方案是创建一个客户端集线器方法showFinalSummary()
,它触发您当前在done()
处理程序中执行的操作,然后在适当的时候从服务器调用此方法(例如,一旦您发送了所有错误更新)。
你的方法:
检查更新中是否有特殊消息信令完成
也可以。