Как использовать серверный таймер из класса Hub, используя SignalR с .NET Core? - PullRequest
0 голосов
/ 29 ноября 2018

Я хочу применить таймер со стороны сервера, используя SignalR в проекте .NET Core.Я могу запустить таймер с пользовательским классом.Таймер должен быть остановлен при нажатии кнопки Стоп и запущен при нажатии кнопки Старт.Это просто демонстрация, которую я создаю, как запуск и остановка.

Я реализовал то же самое, используя Node.js, и у меня нет проблем.В SignalR с .NET Core просто я не могу получить то же самое.

// Custom Timer class to be able to access HubCallerContext and Clients
public class CustomTimer : System.Timers.Timer
{
    public CustomTimer(double interval)
        : base(interval)
    {
    }

    public HubCallerContext callerContext { get; set; }
    public IHubCallerClients<IClient> hubCallerClients { get; set; }
}
public class ApplicationHub : Hub<IClient>
{
    public CustomTimer timer = new CustomTimer(1000);

    // This method will be called on Start button click
    public async Task StartTime()
    { 
        timer.callerContext = Context;
        timer.hubCallerClients = Clients;
        timer.Elapsed += aTimer_Elapsed;
        timer.Interval = 1000;
        timer.Enabled = true;
    }

    // This method will pass time to all connected clients
    void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        timer = (CustomTimer)sender;
        HubCallerContext hcallerContext = timer.callerContext;
        IHubCallerClients<IClient> hubClients = timer.hubCallerClients;

        hubClients.Clients.All.ShowTime(DateTime.Now.Hour.ToString() +
            ":" + DateTime.Now.Minute.ToString() + ":" +
            DateTime.Now.Second.ToString());
    }

    // This should stop running timer on button click event from client
    public async Task StopTime()
    {
        timer.Elapsed -= aTimer_Elapsed;
        timer.Enabled = false;

        await Clients.All.StopTime("Timer Stopped");
    }
}

При вызове метода StopTimer из клиента я не получаю текущий таймер.Если кто-то может мне помочь с этим, я был бы благодарен.

Спасибо
Кодирование означает, что проблемы означают удовольствие.:)

1 Ответ

0 голосов
/ 06 декабря 2018

Сохраните ссылку на timer в static ConcurrentDictionary, проиндексированном ConnectionId.

. Вам просто нужно добавить 3 строки и изменить 2 строки.

public class CustomTimer : System.Timers.Timer
{
    // Add this ↓
    public static ConcurrentDictionary<string, CustomTimer> Timers = new ConcurrentDictionary<string, CustomTimer>();

    // ...
}
public class ApplicationHub : Hub<IClient>
{
    public CustomTimer timer = new CustomTimer(1000);

    // Change this ↓ to `static`, so that `timer.Elapsed -= aTimer_Elapsed;` works
    static void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        // Change this ↓ to `var`
        var timer = (CustomTimer)sender;

        // ...
    }

    public async Task StartTime()
    {
        // Add this ↓
        timer = CustomTimer.Timers.GetOrAdd(Context.ConnectionId, timer);

        // ...
    }

    public async Task StopTime()
    {
        // Add this ↓
        timer = CustomTimer.Timers.GetOrAdd(Context.ConnectionId, timer);

        // ...
    }
}
...