Skip to main content
 首页 » 编程设计

c#之SignalR Core之从 WebAPI 检查连接状态

2024年01月26日31mfrbuaa

我正在使用 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 之间创建单一连接,而不是每次都关闭/打开连接。目前,我将 ChatApi 类创建为单例并在构造函数中初始化集线器连接。

如何在调用 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); 
} 

引用资料: