Search code examples
javascriptsignalrsignalr.client

SignalR: how to wait for connection


I'm using next code snippet to create a SignalR Hub Connection:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/huburl")
    .configureLogging(signalR.LogLevel.Information)
    .build();

async function start() {
    try {
        await connection.start();
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};

// Start the connection.
start();

And after this script, I do some AJAX call to display information on my webpage. In that AJAX call are several status messages I want to receive with my Hub, but I always miss the first x messages.

Some debugging let's me think the connection to my Hub is not yet completed (state is not 'connected') when the first messages are sent by the server.

How can I wait for the Hub to be connected before I do the AJAX call?


Solution

  • Finally, I found something that worked for me:

    Added a boolean 'connected' to the given script:

    let connected = false;
    
    const connection = new signalR.HubConnectionBuilder()
        .withUrl("/huburl")
        .configureLogging(signalR.LogLevel.Information)
        .build();
    
    async function start() {
        try {
            await connection.start();
            console.log("SignalR Connected.");
            connected = true;
        } catch (err) {
            console.log(err);
            setTimeout(start, 5000);
        }
    };
    
    // Start the connection.
    start();
    

    Then created an async method that checks the boolean every 200ms:

    async function WaitForHubConnection() {
        while (true) {
            if (connected) {
                console.log("Connection verified");
                return;
            }
            else {
                await new Promise(resolve => setTimeout(resolve, 200));
            }
        }
    }
    

    And finally I need to await the WaitForHubConnection(), but did not know the jQuery document ready method could be asynchronous, but it works:

    $(document).ready(async function () {
        await WaitForHubConnection();
        $.ajax({
            url: '/ajaxUrl',
            type: 'get',
            data: {  },
            beforeSend: function() { },
            headers: { },
            success: function(data) { }
        });
    });