[英]SignalR call works but doesn't return to client
我正在使用 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
稱為即發即棄,以防萬一發生干擾。 盡管如此,團隊仍會被發送,但最初調用的 hub 方法會在服務器上返回,但不會在客戶端上返回。
所以我試圖重現這個問題,但我失敗了。 此 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 還是自托管都沒有關系。 都不工作。
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 更新,但我猜是點擊了什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.