Comment gérer correctement les mises à jour en utilisant signalr?


Kardon63

J'ai une application cliente Angularet un signalRhub, et aussi un service qui prend un horodatage comme paramètre.

Je veux invoquer une méthode dans le hub lorsque j'appuie sur un bouton de démarrage dans le client, et lorsque la méthode est invoquée, je veux continuer à répertorier toutes les modifications (créer une minuterie) jusqu'à ce que le client appuie sur le bouton d'arrêt, puis je arrêtera la minuterie.

Je veux donc demander ce qui est le mieux:

1- Appelez la méthode invoquée à partir du client avec horodatage, puis créez un setIntervalpour appeler la méthode et lorsque le bouton d'arrêt est enfoncé, je peux l'arrêter.

Avantages: Il est facile de démarrer et d'arrêter la minuterie.

Inconvénients: j'invoque la méthode toutes les 1 s, puis je vérifie auprès du client s'il y a une réponse pour mettre à jour l'interface utilisateur.

2- Invoquez la méthode une fois, puis créez une minuterie pour chaque client sur le serveur et lorsque le client appuie sur le bouton d'arrêt, je peux invoquer une autre méthode pour arrêter la minuterie pour ce client.

Pour: Je vérifie l'horodatage dans le hub et j'enverrai les données au client uniquement si le timeStamp du service> timeStamp localement

Inconvénients: en fait, je ne sais pas comment créer un minuteur pour chaque client, donc si c'est la bonne façon, aidez-moi

Kiril1512

Vous utilisez SignalRpour la communication de données en temps réel. Invoquer une méthode toutes les secondes, c'est juste plaisanter sur le SignalRvisage ... Ce n'est donc pas une solution.

La meilleure solution serait d'utiliser la fonction de groupe.

Exemple:

  1. Le bouton Démarrer ajoutera l'utilisateur à un groupe.
  2. Tant que votre utilisateur fait partie du groupe, il recevra toutes les données dont vous avez besoin. await this.Clients.Group("someGroup").BroadcastMessage(message);
  3. Votre bouton d'arrêt supprimera l'utilisateur du groupe afin qu'il ne reçoive plus de données.

Quelques exemples de code sur le hub:

public async Task Start()
{
    // Add user to the data group

    await this.Groups.AddToGroupAsync(this.Context.ConnectionId, "dataGroup");
}

public async Task Stop()
{
    // Add user to the data group

    await this.Groups.RemoveFromGroupAsync(this.Context.ConnectionId, "dataGroup");
}

Exemple de travail qui envoie des données aux utilisateurs qui ont appuyé sur start et reçoivent des données en temps réel.

private readonly IHubContext<SignalRHub, ISignalRHub> hub;

private readonly IServiceProvider serviceProvider;

public Worker(IServiceProvider serviceProvider, IHubContext<SignalRHub, ISignalRHub> hub)
{
    this.serviceProvider = serviceProvider;
    this.hub = hub;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        await this.hub.Clients.Group("dataGroup").BroadcastMessage(DataManager.GetData());

        this.Logger.LogDebug("Sent data to all users at {0}", DateTime.UtcNow);

        await Task.Delay(1000, stoppingToken);
    }
}

PS: Là où vous avez le travailleur, je suppose que vous avez un gestionnaire qui récupère les données ou quelque chose à envoyer à l'utilisateur.

Edit: Si vous ne voulez pas user worker, vous pouvez toujours juste le minuteur comme:

public class TimerManager
{
    private Timer _timer;
    private AutoResetEvent _autoResetEvent;
    private Action _action;
    public DateTime TimerStarted { get; }

    public TimerManager(Action action)
    {
        _action = action;
        _autoResetEvent = new AutoResetEvent(false);
        _timer = new Timer(Execute, _autoResetEvent, 1000, 2000);
        TimerStarted = DateTime.Now;
    }

    public void Execute(object stateInfo)
    {
        _action();
        if((DateTime.Now - TimerStarted).Seconds > 60)
        {
            _timer.Dispose();
        }
    }
}

Et puis utilisez-le quelque part comme:

 var timerManager = new TimerManager(() => this.hub.Clients.Group("dataGroup").BroadcastMessage(DataManager.GetData()));

Articles connexes


Gatsby PWA Comment gérer les mises à jour?

dknaack J'utilise le gatsby-plugin-offlineplugin et j'aimerais savoir s'il existe un moyen de gérer les mises à jour. Je voudrais afficher un message si une nouvelle version est disponible comme https://medium.com/progressive-web-apps/pwa-create-a-new-update-a