Функция сервера будет запущена один раз для всех пользователей - PullRequest
0 голосов
/ 02 марта 2019

Добрый вечер,

В моем приложении SignalR у меня есть таймер JavaScript, который запускается для всех пользователей "одновременно".В конце этого таймера вызывается серверная функция, и именно здесь начинается эта проблема.Поскольку функция вызывается в конце таймера, каждый подключенный пользователь вызывает ее в одно и то же время, что не является необходимым, поскольку она выдаст одинаковый вывод для всех подключенных пользователей.Будучи логически сложной функцией, если сервер запускает ее без необходимости для всех пользователей, это приводит к большим затратам ресурсов.

Как сделать так, чтобы он запускался только один раз (может быть, при первом вызове (до остановки следующего таймера))?

Заранее спасибо

1 Ответ

0 голосов
/ 02 марта 2019

Вы можете использовать GlobalHost.ConnectionManager.GetHubContext.Это позволит вам получить любой контекст концентратора и затем запустить Clients.All.YourFunction в этом контексте.Это отправит сообщение всем подключенным клиентам, подписанным на этот хаб.

Вам понадобится фоновый процесс, который запускается каждый раз, когда запускается ваша функция JavaScript (кстати, полагаться на то, что все ваши клиенты одновременно вызывают функцию JavaScript, на самом деле не очень хорошая идея; разные местоположения клиентови разная производительность машины будет означать, что они вряд ли будут работать одновременно).

Ниже предполагается, что вы просто запускаете это на одном сервере.Если вы собираетесь развертывать это в веб-ферме, вам нужно будет использовать значение базы данных, чтобы не повторять ту же самую работу, или настроить конкретный экземпляр сервера, который будет отвечать за выполнение вызовов (в противном случае вы получите один вызов на сервер).

Создайте процесс, который выполняется в фоновом режиме (здесь я придерживаюсь простого потока, для этого я фактически использую HangFire, но этого будет достаточно дляпример), например, On App_Start

Thread thread = new Thread(new ThreadStart(YourFunction));
thread.Start();

Затем создайте YourFunction, который будет отвечать за ваши клиентские вызовы:

private bool Cancel = false;

private void YourFunction()
{
    do 
    {
        string foo = "Foo";

        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<YourHub>();
        context.Clients.All.SendYourMessage(foo);

        Thread.Sleep(10000);
    } 
    while(!Cancel)
}

А затем на клиенте просто обработайте сообщение отхаб:

youyHub.client.sendYourMessage = function(message)
{
   // message == "Foo"
};
...