Подтвердить что ты не робот

Как использовать SignalR для уведомления веб-клиентов из ASP.NET MVC 3 о том, что задачи MSMQ были завершены

Как использовать SignalR для реализации уведомлений в системе .NET 4.0, которая состоит из приложения ASP.NET MVC 3 (которое использует проверку подлинности форм), базы данных SQL Server 2008 и службы WCF MSMQ (размещенной в WAS) для обработки данные? Среда выполнения включает IIS 7.5, работающую под управлением Windows Server 2008 R2 Standard Edition.

Я играл только с образцами и не имел обширного знания SignalR.

Вот какой-то фон

Веб-приложение принимает данные от пользователя и добавляет его в таблицу. Затем он вызывает одностороннюю операцию (с ключом базы данных) службы WCF для обработки данных (задачи). Веб-приложение возвращается на страницу, сообщающую пользователю, что данные были отправлены, и они будут уведомлены о завершении обработки. Пользователь может посмотреть страницу "индекс", увидеть, какие задачи завершены, не удалось или выполняется. Они могут продолжать предоставлять больше задач (которые не зависят от предыдущих данных). Они могут закрыть свой браузер и вернуться позже.

Служба WCF на основе MSMQ считывает запись из базы данных и обрабатывает данные. Это может занять от миллисекунд до нескольких минут. После завершения обработки данных запись обновляется с соответствующим статусом (ошибка или сбой) и результатами.

В большинстве случаев служба WCF не выполняет никакой обработки, однако, когда это происходит, пользователи обычно хотят знать, когда это делается как можно скорее. Пользователь по-прежнему будет использовать другие части веб-приложения, даже если у них нет данных, которые будут обрабатываться службой WCF.

Это то, что я сделал

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

Используя jQuery, я опросу сервера для изменений. Действие контроллера проверяет, есть ли какие-либо процессы, которые были изменены (завершены или завершены), и возвратите их в противном случае, подождите несколько секунд и снова проверьте, не возвращаясь к клиенту. Чтобы избежать тайм-аута на клиенте, он вернется через 30 секунд, если не будет никаких изменений. JQuery script ждет некоторое время и снова пытается.

Проблемы

Производительность ухудшается с каждым пользователем, просматривающим страницу. Им не нужно делать что-либо в частности. Мы заметили, что использование памяти Firefox 7+ и Safari увеличивается с течением времени.

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

Я надеюсь, что переход на SignalR может уменьшить количество опросов и тем самым снизить требования к ресурсам, особенно если в базе данных ничего не изменилось. У меня возникли проблемы с получением службы WCF для уведомления клиентов о том, что она выполнена с обработкой задачи, учитывая тот факт, что она использует проверку подлинности на основе форм.

Задав этот вопрос, я надеюсь, что кто-то даст мне лучшее представление о том, как они будут перепроектировать мою схему уведомлений с использованием SignalR, если это вообще возможно.

4b9b3361

Ответ 1

Если я правильно понимаю, вам нужен способ связать задачу с данным пользователем/клиентом, чтобы вы могли сообщить клиенту, когда их задача завершена.

Документация SignalR API говорит мне, что вы можете вызывать методы JS для определенных клиентов на основе идентификатора клиента (https://github.com/SignalR/SignalR/wiki/SignalR-Client). В теории вы могли бы сделать что-то вроде:

  • Хранить идентификатор клиента, используемый SignalR, как часть метаданных задачи:
  • Задайте задачу как обычно.
  • Когда задача обрабатывается и отменяется:
    • Обновите свою базу данных статусом.
    • Используя идентификатор клиента, хранящийся как часть этой задачи, используйте SignalR, чтобы отправить этому клиенту уведомление:

Вы должны иметь возможность получить соединение, которое использует ваш клиент, и отправить им сообщение:

string clientId = processedMessage.ClientId //Stored when you originally queued it.
IConnection connection = Connection.GetConnection<ProcessNotificationsConnection>();
connection.Send(clientId, "Your data was processed");

Это предполагает, что вы сопоставили это соединение, и клиент использовал это соединение для начала запроса обработки данных в первую очередь. В вашей "основной навигационной панели" есть JS, который запустил соединение с конечной точкой ProcessNotificationsConnection, которую вы сопоставили ранее.

EDIT: From https://github.com/SignalR/SignalR/wiki/Hubs

public class MyHub : Hub
{
     public void Send(string data)
     {
     // Invoke a method on the calling client
     Caller.addMessage(data);

     // Similar to above, the more verbose way
     Clients[Context.ClientId].addMessage(data);

     // Invoke addMessage on all clients in group foo
     Clients["foo"].addMessage(data);
     }
}