DEV Community

John Peters
John Peters

Posted on • Updated on

SignalR Client Internals : Making Hub Connections ⚠️ @microsoft/signalr

The back end was an ASP.NET Core 3.1 server.

From the client side, this is what a connection looks like when using a relative path .withURL("/chathub") in the builder.

Alt Text

Notice all the security stuff in the outbound request header.

Alt Text

None of the headers were set in our code! Here's why..

How To Connect To A Server Hub

import { HubConnectionBuilder, LogLevel } from "@microsoft/signalr";
const connection = new HubConnectionBuilder()
  .withUrl("/chatHub")
  .configureLogging(LogLevel.Information)
  .build();
async function start() {
  try {
    await connection.start();
    console.log("connected");
  } catch (err) {
    console.log(err);
    setTimeout(() => start(), 5000);
  }
}
Enter fullscreen mode Exit fullscreen mode

We can see that Singalr makes the configuration and subsequent start easy. Just 5 lines of code.

Warning ⚠️: Do not use the wrong version of signalr! Almost all the examples on the net are pre .net Core.

// this works for asp.net core 3.1
npm i @microsoft/signalr

// this doesn't work for asp.net core 3.1
npm i @aspnet/signalr
Enter fullscreen mode Exit fullscreen mode

The WebSocket Negotiation

SignalR documentation is vague on the protocol used, it simply says it will pick the best protocol at connect time.

This trace was of our front end port 8080 trying to establish a connection with our backend server at 8180.

In our case, the protocol chosen was websockets as shown here. No surprise.

GET /sockjs-node/486/ser1hryo/websocket HTTP/1.1
Host: localhost:8080
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
Upgrade: websocket
Origin: http://localhost:8080
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Sec-WebSocket-Key: 7Kfhbi+lWievbT8RE7h8Lg==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: W7qATLfnyuL27GwOkRGV/sU6GMI=

..o..a["{\"type\":\"liveReload\"}"].Ia["{\"type\":\"overlay\",\"data\":{\"errors\":true,\"warnings\":false}}"].:a["{\"type\":\"hash\",\"data\":\"7250b8a5b13f1cf05ddb\"}"]..a["{\"type\":\"ok\"}"]
Enter fullscreen mode Exit fullscreen mode

Notice in the JSON body above, it shows errors:true. Indeed we are still having an issue connecting. In this case it was due to the fact that the configuation was wrong.

const connection = new HubConnectionBuilder()
  .withUrl("/chatHub")
Enter fullscreen mode Exit fullscreen mode

Documentation Error

The relative URL was not pointed to the backend server where the hub was running! I do not understand why the documentation shows relative urls. See this bug report.

Apparently the WebSocket protocol handshake sends 4, to 5 packets which are immediately are [fin] finned. This is normal behavior. Until you see an error, there's nothing to worry about.

Alt Text

In our next article we continued this journey.

JWP2020 Signalr Hub Connection Internals

Top comments (0)