I have a page component where i add a SignalR HubConnection
:
@page "/test"
@using System.Diagnostics
@using Microsoft.AspNetCore.SignalR.Client
@rendermode InteractiveServer
@implements IAsyncDisposable
<PageTitle>Test</PageTitle>
<button @onclick="SendMessage">Send Message</button>
@foreach(var m in _messages)
{
<p>@m</p>
}
@code {
private readonly List<string> _messages = [];
private HubConnection? _hubConnection;
protected override async Task OnInitializedAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl("https://localhost:5200/message")
.WithAutomaticReconnect()
.Build();
_hubConnection.On<string>("OnMessage", GetMessage);
await _hubConnection.StartAsync();
await base.OnInitializedAsync();
}
private void GetMessage(string message)
{
_messages.Add(message);
Debug.WriteLine(message);
InvokeAsync(StateHasChanged);
}
public async ValueTask DisposeAsync()
{
if (_hubConnection is not null)
{
_hubConnection.Remove("OnMessage");
await _hubConnection.StopAsync();
await _hubConnection.DisposeAsync();
}
}
private async Task SendMessage()
{
await _hubConnection.SendAsync("SendMessage", "Hello");
}
}
With this code you can send a message by clicking a button and every connected client is receiving this message.
On the server i just forward the messages to all clients
public async Task SendMessage(string message)
{
await Clients.All.SendAsync("OnMessage", message);
}
In my GetMessage
function I write the message to the output window Debug.WriteLine(message);
.
When I open the page and click my send button the message gets displayed once on my page and once in my output window.
But if I refresh the page and click again, the message gets displayed once on my page but twice in my output window as if the first event listener is still registered, although it should have been disposed, shouldn’t it?
If you track the current circuit and put that in the output as well you can see that the GetMessage
function gets called from both circuits (the one before and the one after the refresh) (I haven’t put that in the code to keep it simple).
Is the event handler not being disposed correctly? how can it even work when the hubconnection is closed and disposed? what do I misunderstand here?