SignalR Core - 从 WebAPI 检查连接状态

SignalR Core - Check connection state from WebAPI

我正在使用 Microsoft.AspNetCore.SignalR.Client 从我的 WebAPI 项目打开一个连接,以连接和调用我的 SignalR Hub 项目中的方法。这些是托管在不同服务器上的不同项目。

如何查看连接是否已经启动,不尝试启动两次?

我使用以下代码从 WebAPI 连接:

public class ChatApi
{
    private readonly HubConnection _connection;

    public ChatApi()
    {
        var connection = new HubConnectionBuilder();
        _connection = connection.WithUrl("https://localhost:44302/chathub").Build();
    }

    public async Task SendMessage(Msg model)
    {
        await _connection.StartAsync();
        await _connection.SendAsync("Send", model);
    }
}

由于我的 WebAPI 会多次调用 SignalR,因此我想在 WebAPI 和 SignalR 之间创建单一连接,而不是每次都 close/open 连接。目前,我将 ChatApi class 创建为单例并在构造函数中初始化集线器连接。

如何在调用 await _connection.StartAsync(); 之前检查连接是否已启动?

使用:Microsoft.AspNetCore.SignalR.Client v1.0.0-preview1-final

Microsoft.AspNetCore.SignalR.Client v1.1.0+

HubConnection 上有一个 State 属性。

public class ChatApi
{
    private readonly HubConnection _connection;

    public ChatApi()
    {
        _connection = new HubConnectionBuilder()
            .WithUrl("https://localhost:44302/chathub")
            .Build();
    }

    public async Task StartIfNeededAsync()
    {
        if (_connection.State == HubConnectionState.Disconnected)
        {
            await _connection.StartAsync();
        }
    }

    public async Task SendMessage(Msg model)
    {
        await StartIfNeededAsync();
        await _connection.SendAsync("Send", model);
    }
}

参考文献:

Microsoft.AspNetCore.SignalR.Client < v1.1.0

(在撰写本文时,最新版本为 1.0.0-preview2-final。)

没有ConnectionState属性.

您需要自己跟踪状态,方法是在 HubConnection 上订阅 Closed 事件。

public class ChatApi
{
    private readonly HubConnection _connection;

    private ConnectionState _connectionState = ConnectionState.Disconnected;

    public ChatApi()
    {
        var connection = new HubConnectionBuilder();
        _connection = connection.WithUrl("https://localhost:44302/chathub").Build();

        // Subscribe to event
        _connection.Closed += (ex) =>
        {
            if (ex == null)
            {
                Trace.WriteLine("Connection terminated");
                _connectionState = ConnectionState.Disconnected;
            }
            else
            {
                Trace.WriteLine($"Connection terminated with error: {ex.GetType()}: {ex.Message}");
                _connectionState = ConnectionState.Faulted;
            }
        };
    }

    public async Task StartIfNeededAsync()
    {
        if (_connectionState == ConnectionState.Connected)
        {
            return;
        }

        try
        {
            await _connection.StartAsync();
            _connectionState = ConnectionState.Connected;
        }
        catch (Exception ex)
        {
            Trace.WriteLine($"Connection.Start Failed: {ex.GetType()}: {ex.Message}");
            _connectionState = ConnectionState.Faulted;
            throw;
        }
    }

    private enum ConnectionState
    {
        Connected,
        Disconnected,
        Faulted
    }
}

用法:

public async Task SendMessage(Msg model)
{
    await StartIfNeededAsync();
    await _connection.SendAsync("Send", model);
}

参考文献:

至少在 .NET Core 2.1 中,您可以检查 HubConnection 的 State 属性:

if (_connection.State == HubConnectionState.Disconnected) {
        await _connection.StartAsync();
}