SignalR chat connection OK
This commit is contained in:
parent
bb773ba29a
commit
b22a26f61e
43 changed files with 430 additions and 252 deletions
|
|
@ -4,18 +4,37 @@ using System.Threading.Tasks;
|
|||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using PostIt.Models;
|
||||
using PostIt.Services;
|
||||
using Yavsc;
|
||||
|
||||
namespace PostIt.ViewModels.Chat
|
||||
{
|
||||
/// <summary>
|
||||
/// ViewModel pour la gestion du chat,
|
||||
/// incluant la connexion au Hub SignalR,
|
||||
/// la gestion des salons et des utilisateurs connectés.
|
||||
/// </summary>
|
||||
|
||||
public partial class ChatViewModel : ViewModelBase
|
||||
{
|
||||
private readonly Settings _settings;
|
||||
private readonly YavscApiClient? _api;
|
||||
|
||||
// Le paramètre optionnel permet l'instanciation design-time
|
||||
// (Design.DataContext dans ChatPage.axaml) sans conteneur DI.
|
||||
public ChatViewModel(YavscApiClient? api = null)
|
||||
{
|
||||
var app = App.Current as App;
|
||||
_settings = app!.ServiceProvider!.GetRequiredService<Settings>(); // Assurez-vous que _settings est initialisé avant utilisation.
|
||||
_api = api;
|
||||
Status = new StatusNotice("Déconnecté", StatusSeverity.Info,
|
||||
new RelayCheckCommand("Connecter", async () => await ConnectAsync()));
|
||||
}
|
||||
|
||||
private HubConnection? _connection;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string ServerUrl { get; protected set; } = "https://yavsc.pschneider.fr/chathub";
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string CurrentRoom { get; set; } = "General";
|
||||
|
||||
|
|
@ -24,7 +43,6 @@ namespace PostIt.ViewModels.Chat
|
|||
|
||||
[ObservableProperty]
|
||||
public partial StatusNotice Status { get; set; }
|
||||
= new StatusNotice("Déconnecté", StatusSeverity.Info);
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsConnected { get; set; } = false;
|
||||
|
|
@ -40,20 +58,61 @@ namespace PostIt.ViewModels.Chat
|
|||
[RelayCommand]
|
||||
public async Task JoinRoomCommand() => await JoinRoomAsync();
|
||||
|
||||
[RelayCommand]
|
||||
public async Task ChangeNickCommand() => await ChangeNickAsync();
|
||||
|
||||
public override bool CanNavigateNext { get; protected set; } = false;
|
||||
public override bool CanNavigatePrevious { get; protected set; } = true;
|
||||
|
||||
private async Task DisconnectAsync()
|
||||
{
|
||||
if (_connection != null)
|
||||
{
|
||||
await _connection.StopAsync();
|
||||
await _connection.DisposeAsync();
|
||||
_connection = null;
|
||||
}
|
||||
IsConnected = false;
|
||||
Status = new StatusNotice("Déconnecté", StatusSeverity.Info,
|
||||
new RelayCheckCommand("Connecter", async () => await ConnectAsync()));
|
||||
}
|
||||
|
||||
private async Task ConnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Status = new StatusNotice("Connexion en cours...", StatusSeverity.Info);
|
||||
Status = new StatusNotice("Connexion en cours...", StatusSeverity.Info,
|
||||
new RelayCheckCommand("Vérifier la connexion", async () => await CheckConnectionAsync()));
|
||||
|
||||
if (_api == null || !_api.HasValidSession)
|
||||
{
|
||||
Status = new StatusNotice("Session expirée : reconnectez-vous avant d'ouvrir le chat.", StatusSeverity.Error,
|
||||
new RelayCheckCommand("Reconnecter", async () => await ConnectAsync()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Le hub est mappé à la racine du service ("/chathub"),
|
||||
// pas sous le préfixe versionné "/api/v1" : on le retire.
|
||||
var hubBase = _settings.ApiUrl.TrimEnd('/');
|
||||
if (hubBase.EndsWith("/api/v1", StringComparison.OrdinalIgnoreCase))
|
||||
hubBase = hubBase[..^"/api/v1".Length];
|
||||
var hubUrl = hubBase + "/" + Constants.ChatHubPath;
|
||||
|
||||
_connection = new HubConnectionBuilder()
|
||||
.WithUrl(ServerUrl)
|
||||
.WithUrl(hubUrl,
|
||||
|
||||
options =>
|
||||
{
|
||||
// Le hub est [Authorize] : on attache le Bearer OIDC.
|
||||
// AccessTokenProvider est rappelé à chaque reconnexion,
|
||||
// donc on tente un refresh silencieux à chaque appel.
|
||||
// Un refresh mort (invalid_grant) ne doit pas faire
|
||||
// échouer StartAsync avec une exception interne : on
|
||||
// renvoie le token courant (éventuellement expiré) et
|
||||
// le serveur répondra un 401 propre, surfacé à l'UI.
|
||||
options.AccessTokenProvider = async () =>
|
||||
{
|
||||
await _api.TrySilentLoginAsync();
|
||||
return _api.CurrentAccessToken;
|
||||
};
|
||||
})
|
||||
.WithAutomaticReconnect()
|
||||
.Build();
|
||||
|
||||
|
|
@ -88,15 +147,20 @@ namespace PostIt.ViewModels.Chat
|
|||
|
||||
await _connection.StartAsync();
|
||||
IsConnected = true;
|
||||
Status = new StatusNotice("Connecté au Hub SignalR", StatusSeverity.Info);
|
||||
Status = new StatusNotice("Connecté au Hub SignalR", StatusSeverity.Info, new RelayCheckCommand("Déconnecter", async () => await DisconnectAsync()));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Status = new StatusNotice($"Erreur : {ex.Message}", StatusSeverity.Error);
|
||||
Status = new StatusNotice($"Erreur : {ex.Message}", StatusSeverity.Error, new RelayCheckCommand("Reconnecter", async () => await ConnectAsync()));
|
||||
IsConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckConnectionAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private async Task JoinRoomAsync()
|
||||
{
|
||||
if (_connection == null || string.IsNullOrWhiteSpace(CurrentRoom)) return;
|
||||
|
|
@ -115,21 +179,5 @@ namespace PostIt.ViewModels.Chat
|
|||
Messages.Add($"Erreur Join: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ChangeNickAsync()
|
||||
{
|
||||
if (_connection == null || string.IsNullOrWhiteSpace(NickName)) return;
|
||||
|
||||
try
|
||||
{
|
||||
// Appel de la méthode publique 'Nick' du Hub (void)
|
||||
await _connection.InvokeAsync("Nick", NickName);
|
||||
Messages.Add($"Demande de changement de pseudo vers '{NickName}' envoyée.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Messages.Add($"Erreur Nick: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue