SignalR 调用有效,但不返回到客户端



我正在使用 Blazor 构建一个 Web 应用程序,通过 SignalR 同步团队(我的域模型(。(Blazor RC1 WebApp, core31 WebApi(

我的客户端有一个调用,该调用触发服务器将当前团队列表发送给客户端。此方法只有两行:

var currentTeams = await teamService.GetAllTeams().ConfigureAwait(false);
await SendTeamsToClient(currentTeams).ConfigureAwait(false);

这些工作 -SendTeamsToClient获取列表并在客户端上调用另一个 SignalR 方法 - 成功。对象被发送到客户端并在那里正确处理。

唯一的问题是:客户端调用永远不会返回。客户端方法只有一行:

await connection.InvokeAsync(nameof(ServerHub.SubscribeToAndReceiveTeamsAsync));

而且那个永远不会回来。知道为什么吗?

我有一个解决方法,我将该方法称为即发即弃,但这实际上不是一个长期可行的解决方案。

我还尝试让服务器将SendTeamsToClient称为即发即弃,以防万一会以某种方式干扰。尽管如此,团队还是会被发送,但最初调用的中心方法在服务器上返回,但永远不会在客户端上返回。

更新(MCVE 有效,我的项目无效(:

所以我试图重现这个问题,但我失败了。此 MCVE 完美运行:

MCVE 前端,指示成功进入控制台的数字:

public async Task Ping()
{
Console.WriteLine("Sending ping..."); // 1
await c.InvokeAsync("Ping");
Console.WriteLine("ping returned."); // 4
}
public Task Pong(string p)
{
Console.WriteLine("Received pong: "+p); // 2+3
Pongs.Add(p);
StateHasChanged();
return Task.CompletedTask;
}

MCVE 后端:

public async Task Ping()
{
var pongs = new string[]
{
"Pong1",
"Pong2"
};
await SendPongs(pongs).ConfigureAwait(false);
}
public async Task SendPongs(IEnumerable<string> pongs)
{
foreach (var pong in pongs)
{
await Clients.Caller.Pong(pong).ConfigureAwait(false);
}
}

实际项目前端:

public async Task SubscribeToAndReceiveTeamsAsync()
{
Console.WriteLine("Frontend Hub triggering teams"); // This arrives
await connection.InvokeAsync(nameof(ServerHub.SubscribeToAndReceiveTeamsAsync));
Console.WriteLine("Frontend hub done triggering teams."); // This doesn't
}
public Task ReceiveTeam(Team team) // Works completely (teams arrive in view)
{
Console.WriteLine("Frontend hub receiving team "+team.Name);
Console.WriteLine($"Invoking event with {OnNewTeam?.GetInvocationList().Length} listener(s).");
OnNewTeam?.Invoke(team);
return Task.CompletedTask;
}

实际项目后端:

public async Task SubscribeToAndReceiveTeamsAsync()
{
var currentTeams = await teamService.GetAllTeams().ConfigureAwait(false);
Log(currentTeams.Count()); // This arrives with "2"
await SendTeamsToClient(currentTeams).ConfigureAwait(false);
Log("Server done"); // This arrives, therefore this method returns?
}
private async Task SendTeamsToClient(IEnumerable<Team> teams)
{
foreach (var team in teams)
{
await Clients.Caller.ReceiveTeam(team).ConfigureAwait(false);
}
}

不知道为什么一个会起作用而另一个不会。

快速更新:无论我使用 IIS 还是自托管都没有关系。两者都不行。

更新 2

MCVE 和实际项目都使用 DI:

前端:

builder.Services.AddSingleton<HubConnection>(sp => new HubConnectionBuilder().WithUrl($"{builder.HostEnvironment.BaseAddress}signalr").WithAutomaticReconnect().Build());

后端:

app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages(); // <- Not in actual project
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html"); // <- Not in actual project
endpoints.MapHub<MyHub>("/signalr");
});

但是,我确实添加了一个新方法,它有同样的问题:

前端事件调用await connection.InvokeAsync(nameof(ServerHub.SendChatMessage), message);

后端将其发送到其他客户端:

public Task SendChatMessage(string message)
{
Clients.Others.ReceiveMessage(message).ConfigureAwait(false);
return Task.CompletedTask;
} // Debugger says this returns successfully

其他人成功接收消息。

调用方前端调用永远不会返回。

所以我将我的项目升级到 .NET 5,它现在可以完美运行。不知道是关于框架还是 SignalR 更新,但我想有什么点击了?

最新更新