refactor connection

This commit is contained in:
zznty
2022-09-09 17:08:45 +07:00
parent 61186b5ba2
commit 2486f18cc7
3 changed files with 26 additions and 20 deletions

View File

@@ -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();
}
} }

View File

@@ -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" />

View File

@@ -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; }
} }