客户端和服务器之间的SignalR .NET Core (8.0)兼容性

问题描述 投票:0回答:1

我有一个 Web 应用程序,它有一个从 BackgroundService 派生的托管服务,该服务应该定期轮询 Azure 以获取某些数据,并在找到时通过 SignalR 将数据发送到客户端。

我有 2 个客户端:一个 Web 客户端(Razor Pages + javascript),用于获取消息并显示数据。

我正在开发的第二个客户端是桌面客户端。

在网络端,我的监控服务中的轮询功能进行 signalR 调用来传递数据:

var connectionId = _connectionMappingService.GetConnectionId(userName);await 
IndexStats? currentStats = await _indexStatsService.GetIndexStatsAsync(searchIndexName);
_hubContext.Clients.Client(connectionId).SendAsync("IndexStats", currentStats);

我确认已拨打电话,并且数据正确。 “currentStats”是一个复杂的对象。为了简洁起见,我在这里简化了代码......

这里的_hubContext是在服务构造函数中通过DependencyInjection注入的:

    public IndexStatsPolling(ILogger<IndexStatsPolling> logger,
                             IHubContext<NotificationHub> hubContext,
                             IConnectionMappingService connectionMappingService,
                             IAzureSettings azureSettings,
                             IIndexStatsService indexStatsService)
    {
        _logger = logger;
        _hubContext = hubContext;
        _connectionMappingService = connectionMappingService;
        _azureSettings = azureSettings;
        _indexStatsService = indexStatsService;
    }

在桌面端我有 SignalRClient 类:

public class SignalRClient : ISignalRCleint
{
private HubConnection hubConnection;
public event Action<IndexStats> OnIndexStatsReceived;

public SignalRClient(string url)
{
    Init(url);
}

private void Init(string url)
{
    using (Log.VerboseCall())
    {
        string err = "Failed to connect to hub or set event handler";
        try
        {

            hubConnection = new HubConnectionBuilder().WithUrl(url).Build();
            if (String.IsNullOrWhiteSpace(url))
            {
                throw new Exception(err);
            }

            Log.VerboseFormat($"Created hubConnection for URL: {url}");
        
            hubConnection.KeepAliveInterval = new TimeSpan(0,0,5);
            hubConnection.HandshakeTimeout = new TimeSpan(0,2,0);

            // "IndexStats" is just an endpoint alias
            hubConnection.On<IndexStats>("IndexStats", (indexStats) =>
            {
                // Handle the received IndexStats object
                // For example, updating the UI or processing the data
                OnIndexStatsReceived?.Invoke(indexStats);
            });
        }
        catch (Exception ex)
        {
            Log.Verbose(ex);
            throw new Exception(err);
        }
    }
}

public async Task ConnectAsync()
{
    using(Log.VerboseCall())
    {
        try
        {
            await hubConnection.StartAsync();
            Log.VerboseFormat($"Connection state: {hubConnection.State}");
        }
        catch(Exception ex)
        {
            Log.Verbose(ex);
        }
    }
}

public async Task DisconnectAsync()
{
    if (hubConnection != null && hubConnection.State == HubConnectionState.Connected)
    {
        await hubConnection.StopAsync();
    }
}

public event Action<string> OnMessageReceived;
public async Task SendMessageAsync(string message)
{
    // Implementation to send message...
}

}

在桌面上,SignalR 已在 Program.cs 中注册:

            // Add SignalRCleint
        services.AddScoped<SignalRClient, SignalRClient>(provider =>
        {
            var azConfig = provider.GetRequiredService<IAzConfig>();
            var signalRHubUrl = azConfig.AzureADDesktop.SignalRHubUrl; // Now this should have the correct value
            return new SignalRClient(signalRHubUrl);
        });

然后在MainForm.cs中:

private async void MainForm_Load(object sender, EventArgs e)
{
     _signalRClient.OnIndexStatsReceived += SignalRClient_OnIndexStatsReceived;
     await _signalRClient.ConnectAsync();
}

private void SignalRClient_OnIndexStatsReceived(IndexStats indexStats)
{
   using (Log.VerboseCall())
   {
       string indexName = indexStats.IndexName;
       UpdateGlobalStats(UpdateType.IngestData, indexName, indexStats);
   }
}

底线是 SignalRClient_OnIndexStatsReceived 永远不会被调用...

在客户端,我使用以下 NuGet 包: Microsoft.AspNetCore.SignalR.Client 8.0.0 Microsoft.AspNetCore.SignalR.Client.Core 8.0.0

在网络应用程序方面: Microsoft.AspNetCore.SignalR.Core 1.0.15(最新稳定版本)

如果有人对此有任何线索,我会很高兴提供任何解决方案、提示、指针 - 我花了很多时间试图解决它但徒劳......

c# signalr client-server desktop-application
1个回答
0
投票

最终是库不兼容的问题。我的桌面客户端根本没有通过 signalR 服务器进行身份验证,因此在内部,尽管客户端看到了初始连接状态,但服务器中的连接立即断开。

© www.soinside.com 2019 - 2024. All rights reserved.