Aspnetcore: Missing ITransportHeartbeat for SignalR Core

Created on 3 Feb 2020  路  8Comments  路  Source: dotnet/aspnetcore

Hi folks!

First issue here, tried to put it in the right place but not quite sure. Apologize if I done it wrong!

So, we were looking into monitoring signalR alive connections and found out a legacy code of ours where there was a ITransportHeartbeat in signalR for .net framework that was pretty useful for checking hearbeats.

Is there anything like that in signalR for .net core? Or any approach recommended to check connection heartbeats?

area-signalr question

Most helpful comment

There isn't a global hook for all connections, but you can hook the heartbeat for each connection with (pseudo-)code like this in your Hub's OnConnectedAsync:

var heartbeat = Context.Features.Get<IConnectionHeartbeatFeature>();
heartbeat.OnHeartBeat(MyAction, /* a state object that will be passed to MyAction, can be null */);

All 8 comments

There isn't a global hook for all connections, but you can hook the heartbeat for each connection with (pseudo-)code like this in your Hub's OnConnectedAsync:

var heartbeat = Context.Features.Get<IConnectionHeartbeatFeature>();
heartbeat.OnHeartBeat(MyAction, /* a state object that will be passed to MyAction, can be null */);

Thanks @anurse. I'll go give it a try later on and come back with some feedback!

Hey @anurse! We just tried a couple of implementations, but there's something that's still not clear for us:

When is this OnHeartbeat method called? We were not able to track that yet.

When is this OnHeartbeat method called? We were not able to track that yet.

You mean the function you provide to OnHeartbeat? It should be called at a regular interval (about once a second). Can you post a sample showing how you're registering the callback?

I did not asked properly, sorry.

I meant this regular interval that the callback is called. Is it hardcoded by something (if so, by what) or is it configurable?

It's hardcoded right now, you can't configure it. Can you provide more details on what you're trying to do in the heartbeat and how you'd like to configure this? You can always create your own heartbeat.

Our scenario:

  • Various _clients_: application installed in multiple desktops
  • One _server_: a signalR hub in a .NET Core 3.1 webapp with Azure SignalR Service and a Bus to consume some queue.

The usage:

  • When a new signalR connection happens on the _server_, the hub OnConnected method does the following:

    • it identifies who connected, i.e. which _client_.

    • once the _client_ is identified, o new queue consumer is created to send to that specific _client_ some messages published to its specific queue.

    • that done, the _client_ receives via signalR each specific message published on its respective queue and can process them.

  • Infos about each connected _client_ are persisted in a cache in our _server_, so we can keep track of who is on/off and which _signalR connectionId_ each _client_ has.
  • Hub's OnConnected method checks our cache and calls .Abort() to stop the _client_ connection if a connection for that specific _client_ already exists and is active.

Our problem:

  • Due some network latency and windows hibernation, some _clients_ were creating multiple signalR connections with the _server_. The old connections are not dropped, but multiple new are being randomly created. We could measure that by checking the queue consumer count for each _client_: there was supposed to be only one, but there were many of them. And they are only created by the _server_ if a successfull connection with the _client_ is stablished. We also confirmed the number of connections on Azure SignalR Service dashboard.

With the OnHeartbeat we were able to:

  • Create a LatestPing variable in our cache in order to know when a connection was last active. Checking that, we can clear dispose/disable inactive queue consumers for these old connections, by running a scheduled background service which checks our cache.

What is still going on:

  • With the OnHeartbeat we are able to manage these connections that are idle for a while, but when some _client_ computer randomly hibernates, some strange thing happens: new connections are created in batch of 3, 4 and our server does not block/abort them.

Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.

This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!

Was this page helpful?
0 / 5 - 0 ratings