diff --git a/Iceshrimp.Backend/Hubs/ExampleHub.cs b/Iceshrimp.Backend/Hubs/ExampleHub.cs index ce0872f4..52b27715 100644 --- a/Iceshrimp.Backend/Hubs/ExampleHub.cs +++ b/Iceshrimp.Backend/Hubs/ExampleHub.cs @@ -1,10 +1,11 @@ +using Iceshrimp.Shared.HubSchemas; using Microsoft.AspNetCore.SignalR; namespace Iceshrimp.Backend.Hubs; -public class ExampleHub : Hub +public class ExampleHub : Hub, IExampleHubServer { public async Task SendMessage(string user, string message) { - await Clients.All.SendAsync("ReceiveMessage", "SignalR", "ping!"); + await Clients.All.ReceiveMessage("SignalR", "ping!"); } } \ No newline at end of file diff --git a/Iceshrimp.Backend/Hubs/StreamingHub.cs b/Iceshrimp.Backend/Hubs/StreamingHub.cs index 30fc9791..4c696204 100644 --- a/Iceshrimp.Backend/Hubs/StreamingHub.cs +++ b/Iceshrimp.Backend/Hubs/StreamingHub.cs @@ -1,13 +1,21 @@ +using Iceshrimp.Shared.HubSchemas; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; namespace Iceshrimp.Backend.Hubs; [Authorize(Policy = "HubAuthorization")] -public class StreamingHub : Hub +public class StreamingHub : Hub, IStreamingHubServer { public async Task SendMessage(string user, string message) { - await Clients.All.SendAsync("ReceiveMessage", "SignalR", "ping!"); + await Clients.All.ReceiveMessage("SignalR", "ping!"); + } + + public override async Task OnConnectedAsync() + { + await base.OnConnectedAsync(); + var userId = Context.UserIdentifier; + //Clients.User(userId); } } \ No newline at end of file diff --git a/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj b/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj index 42c1a55a..18a8f5cd 100644 --- a/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj +++ b/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj @@ -13,25 +13,26 @@ - - - - + + + + + - + - <_ContentIncludedByDefault Remove="wwwroot\assets\logo.png" /> - <_ContentIncludedByDefault Remove="wwwroot\assets\transparent.png" /> - <_ContentIncludedByDefault Remove="wwwroot\sample-data\weather.json" /> + <_ContentIncludedByDefault Remove="wwwroot\assets\logo.png"/> + <_ContentIncludedByDefault Remove="wwwroot\assets\transparent.png"/> + <_ContentIncludedByDefault Remove="wwwroot\sample-data\weather.json"/> - - + + diff --git a/Iceshrimp.Frontend/Pages/Hub.razor b/Iceshrimp.Frontend/Pages/Hub.razor index ce27d749..81b6ca93 100644 --- a/Iceshrimp.Frontend/Pages/Hub.razor +++ b/Iceshrimp.Frontend/Pages/Hub.razor @@ -1,5 +1,4 @@ @page "/hub" -@using Microsoft.AspNetCore.SignalR.Client @inject NavigationManager Navigation @implements IAsyncDisposable @@ -29,48 +28,5 @@ @code { - private HubConnection? _hubConnection; - private List _messages = []; - private string? _userInput; - private string? _messageInput; - - protected override async Task OnInitializedAsync() - { - _hubConnection = new HubConnectionBuilder() - .WithUrl(Navigation.ToAbsoluteUri("/hubs/example")) - .AddMessagePackProtocol() - .Build(); - - //TODO: authentication is done like this: - //options => { options.AccessTokenProvider = () => Task.FromResult("the_access_token")!; }) - - _hubConnection.On("ReceiveMessage", (user, message) => - { - var encodedMsg = $"{user}: {message}"; - _messages.Add(encodedMsg); - InvokeAsync(StateHasChanged); - }); - - await _hubConnection.StartAsync(); - } - - private async Task Send() - { - if (_hubConnection is not null) - { - await _hubConnection.SendAsync("SendMessage", _userInput, _messageInput); - } - } - - public bool IsConnected => - _hubConnection?.State == HubConnectionState.Connected; - - public async ValueTask DisposeAsync() - { - if (_hubConnection is not null) - { - await _hubConnection.DisposeAsync(); - } - } - + // See Hub.razor.cs } \ No newline at end of file diff --git a/Iceshrimp.Frontend/Pages/Hub.razor.cs b/Iceshrimp.Frontend/Pages/Hub.razor.cs new file mode 100644 index 00000000..ae1e9cb5 --- /dev/null +++ b/Iceshrimp.Frontend/Pages/Hub.razor.cs @@ -0,0 +1,76 @@ +using Iceshrimp.Shared.HubSchemas; +using Microsoft.AspNetCore.SignalR.Client; +using TypedSignalR.Client; + +namespace Iceshrimp.Frontend.Pages; + +public partial class Hub +{ + private HubConnection? _hubConnection; + private IExampleHubServer? _hub; + private List _messages = []; + private string _userInput = ""; + private string _messageInput = ""; + + private class ExampleHubClient(Hub page) : IExampleHubClient, IHubConnectionObserver + { + public Task ReceiveMessage(string user, string message) + { + var encodedMsg = $"{user}: {message}"; + page._messages.Add(encodedMsg); + page.InvokeAsync(page.StateHasChanged); + return Task.CompletedTask; + } + + public Task OnClosed(Exception? exception) + { + return ReceiveMessage("System", "Connection closed."); + } + + public Task OnReconnected(string? connectionId) + { + return ReceiveMessage("System", "Reconnected."); + } + + public Task OnReconnecting(Exception? exception) + { + return ReceiveMessage("System", "Reconnecting..."); + } + } + + protected override async Task OnInitializedAsync() + { + _hubConnection = new HubConnectionBuilder() + .WithUrl(Navigation.ToAbsoluteUri("/hubs/example")) + .AddMessagePackProtocol() + .Build(); + + // This must be in a .razor.cs file for the code generator to work correctly + _hub = _hubConnection.CreateHubProxy(); + + //TODO: authentication is done like this: + //options => { options.AccessTokenProvider = () => Task.FromResult("the_access_token")!; }) + + _hubConnection.Register(new ExampleHubClient(this)); + + await _hubConnection.StartAsync(); + } + + private async Task Send() + { + if (_hub is not null) + { + await _hub.SendMessage(_userInput, _messageInput); + } + } + + private bool IsConnected => _hubConnection?.State == HubConnectionState.Connected; + + public async ValueTask DisposeAsync() + { + if (_hubConnection is not null) + { + await _hubConnection.DisposeAsync(); + } + } +} \ No newline at end of file diff --git a/Iceshrimp.Shared/HubSchemas/ExampleHub.cs b/Iceshrimp.Shared/HubSchemas/ExampleHub.cs new file mode 100644 index 00000000..342c7006 --- /dev/null +++ b/Iceshrimp.Shared/HubSchemas/ExampleHub.cs @@ -0,0 +1,11 @@ +namespace Iceshrimp.Shared.HubSchemas; + +public interface IExampleHubServer +{ + public Task SendMessage(string user, string message); +} + +public interface IExampleHubClient +{ + public Task ReceiveMessage(string user, string message); +} \ No newline at end of file diff --git a/Iceshrimp.Shared/HubSchemas/StreamingHub.cs b/Iceshrimp.Shared/HubSchemas/StreamingHub.cs new file mode 100644 index 00000000..ae1f0d39 --- /dev/null +++ b/Iceshrimp.Shared/HubSchemas/StreamingHub.cs @@ -0,0 +1,11 @@ +namespace Iceshrimp.Shared.HubSchemas; + +public interface IStreamingHubServer +{ + public Task SendMessage(string user, string message); +} + +public interface IStreamingHubClient +{ + public Task ReceiveMessage(string user, string message); +} \ No newline at end of file