簡體   English   中英

SignalR 調用有效但不返回客戶端

[英]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 完美運行:

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 更新,但我猜是點擊了什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM