Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Razor

.NET Core Razor pages (MVC) SignalR Client Error Message connection disconnected with error 'websocket is not in the Open state' Handling

5.00/5 (2 votes)
18 Mar 2024CPOL1 min read 4.4K  
SignalR JavaScript client error: websocket not in Open state resolved
Resolution for common SignalR JavaScript client error websocket not in Open state elucidated through debugging and code placement adjustment.

Introduction

It's quite a common issue to face a thrown error by SignalR JavaScript client "websocket is not in the Open state". Although it may be due to different reasons, one of them is described here.

Background

Researching on the internet for hours and chatting with ChatGPT didn't end up with a solution for my scenario. Finally, I resolved the problem by lots of analyzing, debugging, creating prototype projects, etc. So here is one of the reasons of "websocket is not in the Open state" error message.

Using the Code

Usually, you have the following code in JavaScript side of the Razor pages to implement SignalR client:

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

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

connection.start().then(function () {
 document.getElementById("sendButton").disabled = false; 
}).catch(function (err) {
 return console.error(err.toString()); 
}); 

The connection.start() method throws that "...websocket is not in the Open state".

There is nothing wrong with the code itself, it's just the wrong spot it is placed on. Usually, developers place it inside the razor page's @section Scripts {} block, where the whole JavaScript section goes to. Razor and MVC Frameworks, especially when dealing with complex applications with multiple scripts and libraries, load numerous libraries or scripts which are potential conflicts for the SignalR.

So placing JavaScript code inside a <script> block within the <head> section or at the end of the <body> section of your HTML page is typically the recommended approach to avoid interference with other scripts or libraries.

When I moved SignalR client side code outside of the @section Scripts {}, my SignalR connection was successfully established!

HTML
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/signalrClient.js"></script>

@section Scripts {
   <script>
     ...........
   </script>
}

where signalrClient.js is the js code for SignalR client. Example:

JavaScript
"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable the send button until connection is established.
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var li = document.createElement("li");
    document.getElementById("messagesList").appendChild(li);
    // We can assign user-supplied strings to an element's textContent because it
    // is not interpreted as markup. If you're assigning in any other way, you 
    // should be aware of possible script injection concerns.
    li.textContent = `${user} says ${message}`;
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
    return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

Note, you can't access page Model properties via @Model.MyProperty in signalrClient.js file as this code is outside of the framework's Section block.

That's it! Hope it helps you to save some time in dealing with SignalR implementation. Happy coding!

History

  • 19th March, 2024: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)