From 8d158cc7b9df276dca725e51de20792d2259c12f Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Wed, 26 Jun 2024 16:07:59 +0200 Subject: [PATCH] [backend/streaming] Add connection state handlers, enable stateful auto-reconnect, remove stub message handlers --- Iceshrimp.Backend/Hubs/StreamingHub.cs | 6 --- .../Core/Services/StreamingService.cs | 41 +++++++++---------- Iceshrimp.Frontend/Pages/Streaming.razor | 16 -------- Iceshrimp.Frontend/Pages/Streaming.razor.cs | 15 +------ Iceshrimp.Shared/HubSchemas/StreamingHub.cs | 2 - 5 files changed, 21 insertions(+), 59 deletions(-) diff --git a/Iceshrimp.Backend/Hubs/StreamingHub.cs b/Iceshrimp.Backend/Hubs/StreamingHub.cs index 072cbfb6..6cb19083 100644 --- a/Iceshrimp.Backend/Hubs/StreamingHub.cs +++ b/Iceshrimp.Backend/Hubs/StreamingHub.cs @@ -8,11 +8,6 @@ namespace Iceshrimp.Backend.Hubs; [Microsoft.AspNetCore.Authorization.Authorize(Policy = "HubAuthorization")] public class StreamingHub(StreamingService streamingService) : Hub, IStreamingHubServer { - public async Task SendMessage(string user, string message) - { - await Clients.All.ReceiveMessage("SignalR", "ping!"); - } - public Task Subscribe(StreamingTimeline timeline) { var userId = Context.UserIdentifier ?? throw new Exception("UserIdentifier must not be null at this stage"); @@ -32,7 +27,6 @@ public class StreamingHub(StreamingService streamingService) : Hub? Message; public event EventHandler? Notification; public event EventHandler? NotePublished; public event EventHandler? NoteUpdated; - public event EventHandler? OnConnectionChange; + public event EventHandler? OnConnectionChange; public async Task Connect(StoredUser? user = null) { @@ -40,6 +39,8 @@ internal class StreamingService( _hubConnection = new HubConnectionBuilder() .WithUrl(navigation.ToAbsoluteUri("/hubs/streaming"), Auth) + .WithAutomaticReconnect() + .WithStatefulReconnect() .AddMessagePackProtocol() .Build(); @@ -53,22 +54,26 @@ internal class StreamingService( } catch (Exception e) { - Message?.Invoke(this, $"System: Connection failed - {e.Message}"); + OnConnectionChange?.Invoke(this, HubConnectionState.Disconnected); logger.LogError("Connection failed: {error}", e.Message); } return; - void Auth(HttpConnectionOptions options) - { + void Auth(HttpConnectionOptions options) => options.AccessTokenProvider = () => Task.FromResult(user.Token); - } } - public async Task Send(string userInput, string messageInput) + public async Task Reconnect(StoredUser? user = null) { - if (_hub is not null) - await _hub.SendMessage(userInput, messageInput); + if (_hubConnection is null) + { + await Connect(user); + return; + } + + if (_hubConnection.State is not HubConnectionState.Disconnected) return; + await _hubConnection.StartAsync(); } public bool IsConnected => _hubConnection?.State == HubConnectionState.Connected; @@ -83,13 +88,6 @@ internal class StreamingService( private class StreamingHubClient(StreamingService streaming) : IStreamingHubClient, IHubConnectionObserver { - public Task ReceiveMessage(string user, string message) - { - var encodedMsg = $"{user}: {message}"; - streaming.Message?.Invoke(this, encodedMsg); - return Task.CompletedTask; - } - public Task Notification(NotificationResponse notification) { streaming.Notification?.Invoke(this, notification); @@ -112,19 +110,20 @@ internal class StreamingService( public Task OnClosed(Exception? exception) { - streaming.OnConnectionChange?.Invoke(this, EventArgs.Empty); - return ReceiveMessage("System", "Connection closed."); + streaming.OnConnectionChange?.Invoke(this, HubConnectionState.Disconnected); + return Task.CompletedTask; } public Task OnReconnected(string? connectionId) { - streaming.OnConnectionChange?.Invoke(this, EventArgs.Empty); - return ReceiveMessage("System", "Reconnected."); + streaming.OnConnectionChange?.Invoke(this, HubConnectionState.Connected); + return Task.CompletedTask; } public Task OnReconnecting(Exception? exception) { - return ReceiveMessage("System", "Reconnecting..."); + streaming.OnConnectionChange?.Invoke(this, HubConnectionState.Reconnecting); + return Task.CompletedTask; } } } \ No newline at end of file diff --git a/Iceshrimp.Frontend/Pages/Streaming.razor b/Iceshrimp.Frontend/Pages/Streaming.razor index 4e5ee660..45b0097c 100644 --- a/Iceshrimp.Frontend/Pages/Streaming.razor +++ b/Iceshrimp.Frontend/Pages/Streaming.razor @@ -6,22 +6,6 @@ Home -
- -
-
- -
- - -
-
    @foreach (var message in _messages) { diff --git a/Iceshrimp.Frontend/Pages/Streaming.razor.cs b/Iceshrimp.Frontend/Pages/Streaming.razor.cs index 9d697f9a..90f26bf2 100644 --- a/Iceshrimp.Frontend/Pages/Streaming.razor.cs +++ b/Iceshrimp.Frontend/Pages/Streaming.razor.cs @@ -10,12 +10,8 @@ public partial class Streaming : IAsyncDisposable [Inject] private StreamingService StreamingService { get; init; } = null!; private readonly List _messages = []; - private string _userInput = ""; - private string _messageInput = ""; - protected override async Task OnInitializedAsync() { - StreamingService.Message += OnMessage; StreamingService.Notification += OnNotification; StreamingService.NotePublished += OnNotePublished; StreamingService.NoteUpdated += OnNoteUpdated; @@ -23,14 +19,6 @@ public partial class Streaming : IAsyncDisposable await StreamingService.Connect(); } - private async Task Send() => await StreamingService.Send(_userInput, _messageInput); - - private async void OnMessage(object? _, string message) - { - _messages.Add(message); - await InvokeAsync(StateHasChanged); - } - private async void OnNotification(object? _, NotificationResponse notification) { _messages.Add($"Notification: {notification.Id} ({notification.Type})"); @@ -42,7 +30,7 @@ public partial class Streaming : IAsyncDisposable _messages.Add($"Note: {data.note.Id} ({data.timeline.ToString()})"); await InvokeAsync(StateHasChanged); } - + private async void OnNoteUpdated(object? _, (StreamingTimeline timeline, NoteResponse note) data) { _messages.Add($"Note updated: {data.note.Id} ({data.timeline.ToString()})"); @@ -51,7 +39,6 @@ public partial class Streaming : IAsyncDisposable public async ValueTask DisposeAsync() { - StreamingService.Message -= OnMessage; StreamingService.Notification -= OnNotification; StreamingService.NotePublished -= OnNotePublished; StreamingService.NoteUpdated -= OnNoteUpdated; diff --git a/Iceshrimp.Shared/HubSchemas/StreamingHub.cs b/Iceshrimp.Shared/HubSchemas/StreamingHub.cs index b79dae15..eb2ddcfd 100644 --- a/Iceshrimp.Shared/HubSchemas/StreamingHub.cs +++ b/Iceshrimp.Shared/HubSchemas/StreamingHub.cs @@ -4,14 +4,12 @@ namespace Iceshrimp.Shared.HubSchemas; public interface IStreamingHubServer { - public Task SendMessage(string user, string message); public Task Subscribe(StreamingTimeline timeline); public Task Unsubscribe(StreamingTimeline timeline); } public interface IStreamingHubClient { - public Task ReceiveMessage(string user, string message); public Task Notification(NotificationResponse notification); public Task NotePublished(List timelines, NoteResponse note); public Task NoteUpdated(List timelines, NoteResponse note);