refactor connection
This commit is contained in:
@@ -1,13 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Refit;
|
using Refit;
|
||||||
using Websocket.Client;
|
using Websocket.Client;
|
||||||
namespace TorchRemote.Services;
|
namespace TorchRemote.Services;
|
||||||
|
|
||||||
public class ApiClientService
|
public class ApiClientService : IDisposable
|
||||||
{
|
{
|
||||||
public const string Version = "v1";
|
public const string Version = "v1";
|
||||||
public string BearerToken
|
public string BearerToken
|
||||||
@@ -16,37 +20,32 @@ public class ApiClientService
|
|||||||
set => _client.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse($"Bearer {value}");
|
set => _client.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse($"Bearer {value}");
|
||||||
}
|
}
|
||||||
private readonly HttpClient _client = new();
|
private readonly HttpClient _client = new();
|
||||||
|
private readonly CancellationTokenSource _tokenSource = new();
|
||||||
public string BaseUrl
|
public string BaseUrl
|
||||||
{
|
{
|
||||||
get => _client.BaseAddress?.ToString() ?? "http://localhost";
|
get => _client.BaseAddress?.ToString() ?? "http://localhost";
|
||||||
set => _client.BaseAddress = new($"{value}/api/{Version}/");
|
set => _client.BaseAddress = new($"{value}/api/{Version}/");
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler? Connected;
|
public IObservable<bool> Connected { get; }
|
||||||
|
|
||||||
public ApiClientService()
|
public ApiClientService()
|
||||||
{
|
{
|
||||||
Api = RestService.For<IRemoteApi>(_client);
|
Api = RestService.For<IRemoteApi>(_client);
|
||||||
Task.Run(ConnectionTimer);
|
Connected = ConnectionTimer(_tokenSource.Token).ToObservable();
|
||||||
}
|
}
|
||||||
public IRemoteApi Api { get; }
|
public IRemoteApi Api { get; }
|
||||||
|
|
||||||
private async Task ConnectionTimer()
|
private async IAsyncEnumerable<bool> ConnectionTimer([EnumeratorCancellation] CancellationToken token)
|
||||||
{
|
{
|
||||||
while (true)
|
while (!token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000, token);
|
||||||
try
|
var success = (await Api.GetServerStatus()).Error is null;
|
||||||
{
|
yield return success;
|
||||||
await Api.GetServerStatus();
|
if (success)
|
||||||
break;
|
await Task.Delay(TimeSpan.FromSeconds(30), token);
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connected?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<WebsocketClient> WatchChatAsync() => StartWebsocketConnectionAsync("live/chat");
|
public Task<WebsocketClient> WatchChatAsync() => StartWebsocketConnectionAsync("live/chat");
|
||||||
@@ -72,4 +71,10 @@ public class ApiClientService
|
|||||||
await client.Start();
|
await client.Start();
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_client.Dispose();
|
||||||
|
_tokenSource.Cancel();
|
||||||
|
_tokenSource.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
||||||
<PackageReference Include="ReactiveUI.Fody" Version="18.3.1" />
|
<PackageReference Include="ReactiveUI.Fody" Version="18.3.1" />
|
||||||
<PackageReference Include="Refit" Version="6.3.2" />
|
<PackageReference Include="Refit" Version="6.3.2" />
|
||||||
|
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||||
<PackageReference Include="System.Text.Json" Version="7.0.0-preview.6.22324.4" />
|
<PackageReference Include="System.Text.Json" Version="7.0.0-preview.6.22324.4" />
|
||||||
<PackageReference Include="Websocket.Client" Version="4.4.43" />
|
<PackageReference Include="Websocket.Client" Version="4.4.43" />
|
||||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.3.4" />
|
<PackageReference Include="XamlNameReferenceGenerator" Version="1.3.4" />
|
||||||
|
@@ -39,9 +39,10 @@ public class RemoteServerViewModel : TabViewModelBase, IScreen
|
|||||||
.Select<ServerNavItem, IRoutableViewModel>(b => b.ViewModel)
|
.Select<ServerNavItem, IRoutableViewModel>(b => b.ViewModel)
|
||||||
.InvokeCommand(Router, x => x.Navigate);
|
.InvokeCommand(Router, x => x.Navigate);
|
||||||
|
|
||||||
Observable.FromEventPattern(_clientService, nameof(_clientService.Connected))
|
_clientService.Connected
|
||||||
|
.DistinctUntilChanged()
|
||||||
.ObserveOn(RxApp.MainThreadScheduler)
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(_ => Connected = true);
|
.ToPropertyEx(this, x => x.Connected);
|
||||||
|
|
||||||
this.WhenAnyValue(x => x.Connected)
|
this.WhenAnyValue(x => x.Connected)
|
||||||
.Where(b => b)
|
.Where(b => b)
|
||||||
@@ -57,6 +58,5 @@ public class RemoteServerViewModel : TabViewModelBase, IScreen
|
|||||||
public RoutingState Router { get; set; } = new();
|
public RoutingState Router { get; set; } = new();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
[Reactive]
|
public extern bool Connected { [ObservableAsProperty] get; }
|
||||||
public bool Connected { get; set; }
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user