Определить клиент, закрывающий соединение Blazor - PullRequest
1 голос
/ 21 апреля 2020

У меня есть все oop, которое я запускаю все время, пока клиент находится на странице, но у меня нет возможности закрыть l oop, чтобы он всегда работал, даже когда пользователь уже отключился. Есть ли метод жизненного цикла, который запускается, когда пользователь закрывает соединение? или есть другой способ?

Ответы [ 2 ]

2 голосов
/ 21 апреля 2020

Если это отдельная страница, над которой она работает, она должна наследовать OwningComponentBase (предпочтительно) или реализовать IDisposable, затем установить l oop с флагом выхода или если задана задача зацикливания CancellationTokenSource и токен на задании. Затем, когда пользователь покидает страницу и закрывает ее, переопределите метод Dispose и либо установите флаг выхода, либо установите для источника токена значение «Отменено», и ваш l oop должен выйти.

Если вам нужно go глубже, В этой ссылке к документам обсуждаются схемы на стороне сервера, которые могут помочь. Для клиентской стороны методы dispose должны работать, если они выполняются в браузере, но если у вас запущен процесс на стороне сервера через API, вам нужно позволить этому запуску идти своим ходом, так как клиентская сторона сеанса будет в сбойном состоянии и если вы используете JWT, токен будет иметь собственный срок действия и сервер не будет задействован. Я бы порекомендовал строить тайм-ауты, где это необходимо, в качестве гарантии.

1 голос
/ 21 апреля 2020

Я не уверен, что простая реализация интерфейса IDisposable может вам в этом помочь, но реализация обработчика схемы Blazor Server может помочь. Я смутно припоминаю, что такой же вопрос был задан вам в stackoverflow ... OP попытался реализовать интерфейс IDisposable, но безрезультатно. Я отвечал один или два раза на этот вопрос, а затем на следующий ... Я публикую код из своего ответа, и я надеюсь, что это поможет вам ...

CircuitHandlerService.cs

using Microsoft.AspNetCore.Components.Server.Circuits;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;


namespace BlazorCircuitHandler.Services
{
  public class CircuitHandlerService : CircuitHandler 
  {
    public ConcurrentDictionary<string, Circuit> Circuits { get; set; }
    public event EventHandler CircuitsChanged;

    protected virtual void OnCircuitsChanged()
    => CircuitsChanged?.Invoke(this, EventArgs.Empty);

    public CircuitHandlerService()
    {
        Circuits = new ConcurrentDictionary<string, Circuit>();
    }

    public override Task OnCircuitOpenedAsync(Circuit circuit, 
                              CancellationToken cancellationToken)
    {
        Circuits[circuit.Id] = circuit;
        OnCircuitsChanged();
        return base.OnCircuitOpenedAsync(circuit, cancellationToken);
    }

    public override Task OnCircuitClosedAsync(Circuit circuit, 
                  CancellationToken cancellationToken)
    {
        Console.WriteLine("OnCircuitClosedAsync");
        Circuit circuitRemoved;
        Circuits.TryRemove(circuit.Id, out circuitRemoved);
        OnCircuitsChanged();
        return base.OnCircuitClosedAsync(circuit, cancellationToken);
    }

    public override Task OnConnectionDownAsync(Circuit circuit, 
                    CancellationToken cancellationToken)
    {
        Console.WriteLine("OnConnectionDownAsync");
        return base.OnConnectionDownAsync(circuit, cancellationToken);
    }

    public override Task OnConnectionUpAsync(Circuit circuit, 
        CancellationToken cancellationToken)
    {
        return base.OnConnectionUpAsync(circuit, cancellationToken);
    }

  }
 }

Использование

@page "/"

@using Microsoft.AspNetCore.Components.Server.Circuits
@using BlazorCircuitHandler.Services

@inject CircuitHandler circuitHandler
@implements IDisposable



 <h1>Hello, world!</h1>

 Welcome to your new app.

<p>
 Number of Circuits: @((circuitHandler as 
    BlazorCircuitHandler.Services.CircuitHandlerService).Circuits.Count)
<ul>
    @foreach (var circuit in (circuitHandler as 
          BlazorCircuitHandler.Services.CircuitHandlerService).Circuits)
    {
        <li>@circuit.Key</li>
    }
</ul>
</p>

@code {

protected override void OnInitialized()
{
      // register event handler
    (circuitHandler as CircuitHandlerService).CircuitsChanged += 
                                          HandleCircuitsChanged;
}

public void Dispose()
{
    // unregister the event handler when the component is destroyed
    (circuitHandler as CircuitHandlerService).CircuitsChanged -= 
                                             HandleCircuitsChanged;
}

public void HandleCircuitsChanged(object sender, EventArgs args)
{
    // notify the UI that the state has changed
    InvokeAsync(() => StateHasChanged());
 }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
   // ........ .....
   services.AddSingleton<CircuitHandler>(new CircuitHandlerService());
}
...