Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get SignalR to reconnect on Console Client

I am trying to write a console application that receives changes from my website and does something when triggered. I got it to connect and work just fine, however should the website go down for any reason and for any duration of time, the client never reconnects. Here is my client code:

public class MyBot
{
    HubConnection connection;

    public async Task RunAsync()
    {
        try
        {
            connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:7178/MyHub")
                .WithAutomaticReconnect()
                .Build();

            connection.Closed += async (error) =>
            {
                Console.WriteLine("Connection Lost");
                await Task.Delay(new Random().Next(0, 5) * 1000);
                await connection.StartAsync();
                await connection.InvokeAsync("JoinBots");
            };

            connection.On<string, string>("DoSomething", (arg1, arg2) =>
            {
                //Do Something
            });

            await connection.StartAsync();
            await connection.InvokeAsync("JoinBots");
        }
        catch
        {
            Console.WriteLine("Failed to connect to Website");
        }
    }
}

In my console the "Connection Lost" never is written. If fact none of the catch even fire. What am I doing wrong?

like image 832
Bagzli Avatar asked Oct 21 '25 05:10

Bagzli


1 Answers

So it would seem that the connection.Closed event only fires when it is done retrying. Not 100% sure on this but I think its how it works.

There is a connection.Reconnected method that fires when a connection is lost. which only fires once, so here you can pug logs that a connection was lost.

The options WithAutomaticReconnect() takes an argument and here you can setup your own custom reconnection. If you want to keep trying and never stop or stop after 4 attempts or however you see fit.

Once I implemented the above everything worked fine.

Edit:

Here is example:

var connection = new HubConnectionBuilder()
                    .WithUrl($"someurl")
                    .WithAutomaticReconnect(new SignalRRetryPolicy())
                    .Build();

Then you would build your class like this:

public class SignalRRetryPolicy : IRetryPolicy
{
    public TimeSpan? NextRetryDelay(RetryContext retryContext)
    {
        //replace this with whatever logic you want. Below is just example how to retry every 30 seconds and never stop. I would advise putting in place some sort of a stop after maybe few hours or such. But it depends on your scenario.
        return TimeSpan.FromSeconds(30);
    }
}
like image 151
Bagzli Avatar answered Oct 23 '25 18:10

Bagzli