我正在编写一个使用SignalR从Web浏览器中的JavaScript进行调用的ASP.NET Core 2.2 C#Web应用程序。在服务器端,我像这样初始化SignalR:
public static void ConfigureServices(IServiceCollection services)
{
...
// Use SignalR
services.AddSignalR(o =>
{
o.EnableDetailedErrors = true;
});
}
和
public static void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
// Route to SignalR hubs
app.UseSignalR(routes =>
{
routes.MapHub<ClientProxySignalR>("/clienthub");
});
...
}
我的SignalR Hub类具有如下方法:
public class ClientProxySignalR : Hub
{
...
public async Task<IEnumerable<TagDescriptor>> GetRealtimeTags(string project)
{
return await _requestRouter.GetRealtimeTags(project).ConfigureAwait(false);
}
...
}
在客户端:
var connection = new signalR.HubConnectionBuilder()
.withUrl("/clienthub")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().then(function () {
...
// Enable buttons & stuff so you can click
...
}
document.getElementById("tagGetter").addEventListener("click", function (event) {
connection.invoke("GetRealtimeTags", "Project1").then(data => {
...
// use data
...
}
}
所有这些都可以正常工作,并且可以异步工作。因此,如果我单击“ tagGetter”按钮,它将在我的Hub上调用“ GetRealtimeTags”方法,并且在数据返回时将调用“ then”部分。的确,如果这需要一段时间才能运行,并且同时我再次单击“ tagGetter”按钮,则至少在JavaScript中会再次调用.invoke(“ GetRealtimeTags”)。
但是...这是发生问题的地方。尽管第二个调用是在JavaScript中进行的,但直到第一个调用完成后,它才会触发SignalR Hub类中的相应方法。这与我对应该发生的事情的理解不符。我认为,每次向服务器调用SignalR集线器方法都会导致创建一个新的集线器类实例来处理该调用。相反,第一个电话似乎阻止了第二个电话。
如果我在JavaScript代码中创建了两个不同的连接,则可以同时对它们进行两次调用,而不会阻塞另一个。但是我知道这不是完成这项工作的正确方法。
所以我的问题是:在这种情况下我做错了什么?
最佳答案
这是通过设计Websocket来确保消息以正确的顺序传递的。
您可以参考此以获取更多信息:https://hpbn.co/websocket/
引:
前面的示例尝试将应用程序更新发送到
服务器,但前提是之前的邮件已从
客户的缓冲区。为什么要打扰这种检查呢?所有WebSocket消息
传送的确切顺序是
客户。结果,排队消息的积压很大,甚至
单个大邮件,将延迟排在后面的邮件的传递
它-行头阻塞!
他们还提出了一种解决方法:
要变通解决此问题,该应用程序可以拆分大消息
分成较小的块,仔细监视bufferedAmount值以
避免行首阻塞,甚至实现自己的优先级队列
待处理的邮件,而不是盲目地将它们全部排队
插座。
关于c# - ASP.NET Core 2.2 SignalR缓冲调用而不是异步调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55192314/