SignalR: The 'SendCoreAsync' method cannot be called if the connection is not active

Viewed 1723

I'm working on an ASP.NET Core web application in which users through the client (OrderClient) will be able to send and receive messages using a SignalR hub (OrderHub). I'm new to razor pages, so I am probably missing something obvious.

For simplicity's sake, the UserConnected-method in the OrderHub looks like this:

    public async Task UserConnected(string someString)
    {
        log.Info(someString);
    }

My index.cshtml.cs looks like this:

public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;
    private HubConnection _hubConnection;

    [BindProperty]
    public string Test { get; set; }

    public IndexModel(ILogger<IndexModel> logger)
    {
        _logger = logger;
        _hubConnection = new HubConnectionBuilder().WithUrl("https://localhost:44336/orderhub").WithAutomaticReconnect().Build();
    }

    public async void OnGet()
    {
        await _hubConnection.StartAsync();
    }

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }
        //await _hubConnection.StartAsync();

        await _hubConnection.SendAsync("UserConnected", Test);

        return RedirectToPage("./Index");
    }
}

And my index.cshtml looks like this:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<form method="post">
    Name:
    <input asp-for="Test" />
    <input type="submit" />
</form>

I've tried debugging in the OrderHub, and the connection is established correctly when the IndexModel-constructor is invoked along with the OnGet()-method. However, when I click the button on the page, the connection has been lost and I am shown the error "InvalidOperationException: The 'SendCoreAsync' method cannot be called if the connection is not active". The state of the hub, when debugging, also shows as "Disconnected". I am assuming I am handling the lifetime of the hub incorrectly, however I fail to see how to fix it.

If I recreate the connection each time, the code works and the text from the input field is received correctly by the hub. However, since the connection is closed when not reconnecting each time, I assume the hub won't be able to send information to the client, which is the issue I foresee having. This could also be wrong, and that the client is able to receive messages - I haven't tried this yet.

1 Answers

Your IndexModel is transient (new instance per HTTP request) on the server, and thus the new SignalR client on the server is not connected during a post request.

Instead of using a form to post back, persist a SignalR JavaScript client in the browser and invoke hub methods there, via JavaScript. See https://docs.microsoft.com/aspnet/core/signalr/javascript-client .

Related