84 lines
3.0 KiB
C#
84 lines
3.0 KiB
C#
using Microsoft.AspNetCore.SignalR.Client;
|
|
|
|
namespace ClientApiPoC.Shared.SignalR {
|
|
public class TunnelClient : NotifyPropertyChangedBase, IDisposable, IAsyncDisposable {
|
|
#region IDisposable-Implementierung
|
|
private bool _disposed;
|
|
|
|
protected virtual void Dispose(bool disposing) {
|
|
if (!_disposed) {
|
|
if (disposing) {
|
|
_ = this.DisposeAsync();
|
|
}
|
|
_disposed = true;
|
|
}
|
|
}
|
|
|
|
public void Dispose() {
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public async ValueTask DisposeAsync() {
|
|
await DisconnectAsync();
|
|
}
|
|
#endregion
|
|
|
|
private HubConnection? _connection = null;
|
|
|
|
public bool IsConnected => (this.ConnectionState == HubConnectionState.Connected);
|
|
|
|
public bool IsConnecting => (this.ConnectionState == HubConnectionState.Connecting || this.ConnectionState == HubConnectionState.Reconnecting);
|
|
|
|
protected HubConnectionState ConnectionState => (_connection?.State ?? HubConnectionState.Disconnected);
|
|
|
|
public async Task ConnectAsync(string url, Action<HubConnection> configureConnection) {
|
|
try {
|
|
if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url));
|
|
if (this.IsConnected) throw new InvalidOperationException("SignalR connection is already established.");
|
|
_connection = new HubConnectionBuilder().WithUrl(url).WithAutomaticReconnect().Build();
|
|
_connection.Reconnecting += Connection_Reconnecting;
|
|
_connection.Reconnected += Connection_Reconnected;
|
|
_connection.Closed += Connection_Closed;
|
|
configureConnection(_connection);
|
|
await _connection.StartAsync();
|
|
} finally {
|
|
await UpdateStateAsync();
|
|
}
|
|
}
|
|
|
|
public async Task DisconnectAsync() {
|
|
try {
|
|
if (_connection == null) return;
|
|
try {
|
|
if (this.IsConnected) await _connection.StopAsync();
|
|
} catch { }
|
|
_connection.Reconnecting -= Connection_Reconnecting;
|
|
_connection.Reconnected -= Connection_Reconnected;
|
|
_connection.Closed -= Connection_Closed;
|
|
await _connection.DisposeAsync();
|
|
_connection = null;
|
|
} finally {
|
|
await UpdateStateAsync();
|
|
}
|
|
}
|
|
|
|
private async Task Connection_Reconnecting(Exception? arg) {
|
|
await UpdateStateAsync();
|
|
}
|
|
|
|
private async Task Connection_Reconnected(string? arg) {
|
|
await UpdateStateAsync();
|
|
}
|
|
|
|
private async Task Connection_Closed(Exception? arg) {
|
|
await UpdateStateAsync();
|
|
}
|
|
|
|
private async Task UpdateStateAsync() {
|
|
OnPropertyChanged(nameof(IsConnected));
|
|
OnPropertyChanged(nameof(IsConnecting));
|
|
await Task.CompletedTask;
|
|
}
|
|
}
|
|
} |