Система уведомлений SignalR - PullRequest
2 голосов
/ 06 марта 2012

Я впервые играю с SignalR. Я пытаюсь создать систему уведомлений, в которой сервер регулярно проверяет, есть ли что-то (база данных запросов) для широковещательной рассылки, и если она есть, то она передает ее всем клиентам. Я наткнулся на этот пост в Stackoverflow и мне было интересно, действительно ли изменение кода для выполнения вызова БД с определенным интервалом действительно является правильным способом сделать это. Если нет, то есть ли лучший способ сделать это?

Я видел много вопросов, связанных с уведомлениями, но не содержащих ни одного кода. Отсюда и этот пост.

Это точный код, который я использую:

public class NotificationHub : Hub
{
    public void Start()
    {
        Thread thread = new Thread(Notify);
        thread.Start();
    }

    public void Notify()
    {
        List<CDCNotification> notifications = new List<CDCNotification>();
        while (true)
        {
            notifications.Clear();
            notifications.Add(new CDCNotification() 
                { 
                    Server = "Server A", Application = "Some App", 
                    Message = "This is a long ass message and amesaadfasd asdf message", 
                    ImgURL = "../Content/Images/accept-icon.png" 
                });
            Clients.shownotification(notifications);
            Thread.Sleep(20000);
        }
    }
}

Я уже вижу странное поведение, когда уведомления приходят чаще, чем они должны были. Хотя я должен получать его каждые 20 секунд, я получаю его примерно через 4-5 секунд и получаю несколько сообщений. Вот мой клиент:

var notifier = $.connection.notificationHub;
notifier.shownotification = function (data) {
    $.each(data, function (i, sample) {
        var output = Mustache.render("<img class='pull-left' src='{{ImgURL}}'/> <div><strong>{{Application}}</strong></div><em>{{Server}}</em> <p>{{Message}}</p>", sample);
        $.sticky(output);
    });
};

$.connection.hub.start(function () { notifier.start(); });

Ответы [ 2 ]

6 голосов
/ 06 марта 2012

Пара замечаний:

  1. Как только второй клиент подключится к вашему серверу, будет 2 потока, отправляющих уведомления, поэтому, если у вас более одного клиента, интервалы будут меньше 20 с.
  2. Обработка потоков вручную в ASP.NET считается плохой практикой, по возможности этого следует избегать.
  3. В общем, это очень похоже на опрос, что является своего рода вещью, от которой SignalR позволяет избавиться оттак как вам не нужно сигнализировать серверу / клиенту

Чтобы решить эту проблему, вам нужно сделать что-то вроде этого (опять же, потоки в веб-приложении, как правило, не очень хорошая идея):

public class NotificationHub : Hub
{
  public static bool initialized = false;
  public static object initLock = new object();

  public void Start()
  {
    if(initialized)
      return;

    lock(initLock)
    {
      if(initialized)
        return;

      Thread thread = new Thread(Notify);
      thread.Start();

      initialized = true;
    }
  }

  public void Notify()
  {
    List<CDCNotification> notifications = new List<CDCNotification>();
    while (true)
    {
      notifications.Clear();
      notifications.Add(new CDCNotification() { Server = "Server A", Application = "Some App", Message = "This is a long ass message and amesaadfasd asdf message", ImgURL = "../Content/Images/accept-icon.png" });
      Clients.shownotification(notifications);
      Thread.Sleep(20000);
    }
  }
}

Инициализированный флаг static предотвращает создание нескольких потоков.Блокировка вокруг него гарантирует, что флаг установлен только один раз.

1 голос
/ 01 апреля 2012

Я работаю над той же задачей здесь.Вместо того, чтобы постоянно проверять базу данных, я создал свои собственные события и прослушиватель, где событие ПОДНИМАЕТСЯ, когда УВЕДОМЛЕНИЕ ДОБАВЛЕНО :) Что вы думаете об этом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...