Cannot send data if the connection is not in the 'Connected' State

Viewed 15741

Doing a really simple call to setup connect/stop using SignalR in Angular 6 where I had the following code:

signalR.helper.ts

  public static setupHub<T>(hubUrl: string, eventName: string, callback: (data: T) => void, ...params: SignalRParam[]): HubConnection {
    const token = localStorage.getItem(appConstant.token);
    const url = this.buidlUrl(hubUrl, ...params);
    const connection = new HubConnectionBuilder()
        .withUrl(url,
            { transport: HttpTransportType.WebSockets, accessTokenFactory: () => token })
        .build();
    environment.production && connection.start();
    !environment.production && connection.start().catch(err => console.error(err.toString()));
    connection.on(eventName, callback);
    return connection;
}

If I try to login on my page,I keep getting this error on console:

signalR.helper.ts:19 Error: Cannot send data if the connection is not in the 'Connected' State.

I'm new to SignalR and Angular and why I keep getting this error ?

3 Answers

Make sure the promise returned from ".start()" has resolved before invoking any methods. You may want to change your method to return the promise so you can chain other methods off of it. Or switch to using the async/await pattern in the method.

Also, make sure you're not accidentally calling ".stop()". In my case, I had an observable that watched if users were authenticated or not and called ".stop()" if they logged off. The problem was that the observable indicated that the user was not authenticated for a brief moment as the page was loading - which caused a race condition where sometimes it would work and sometimes it would not.

Please provide more details such as your Startup.cs, or where you have added the following lines in your *.cshtml:

<script src="~/lib/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

If you don't navigate to the *.cshtml page that has the above then SignalR will not be able to create the Hub for you. If you want it to be available throughout the web app then put the above in _Layout.cshtml.

That will cause errors like this:

POST http://myserver.com/chatHub/negotiate 404 (Not Found)
(anonymous) @ XhrHttpClient.ts:84
XhrHttpClient.send @ XhrHttpClient.ts:30
Utils.ts:179 [2019-06-14T19:21:39.774Z] Error: Failed to complete negotiation with the server: Error: Not Found
ConsoleLogger.log @ Utils.ts:179
Utils.ts:179 [2019-06-14T19:21:39.774Z] Error: Failed to start the connection: Error: Not Found
Error: Cannot send data if the connection is not in the 'Connected' State.

For more details please see:

Overview: https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-2.2

Hubs: https://docs.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-2.2

Clients: https://docs.microsoft.com/en-us/aspnet/core/signalr/javascript-client?view=aspnetcore-2.1#call-hub-methods-from-client

You need first to make sure that you have started your connection

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

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

connection.onclose(async () => {
    await start();
});

// Start the connection.
start();
Related