2016-03-17 3 views
4

У меня есть приложение .NET, которое работает на NancyFx (должно быть агностически для платформы). У меня есть требование, чтобы мне нужно было отправить уведомление, когда происходит определенное событие (подписка). В уведомлении будет реализован этот интерфейс:.Net messaging pub/sub pattern

public interface INotification 
{ 
    public void Notify(); 
} 

Будет много различных реализаций для этого, например, Электронная почта, Pushbullet, Pushover и т. Д.

То, с чем я борюсь, - это как реализовать это, чтобы все реализации INotification выполняли Notify() при наличии подписки.

Может ли кто-нибудь указать мне в правильном направлении.

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

Таким образом, приложение является самообслуживанием, клиент и сервер расположены на компьютере пользователя, и он не разговаривает с внешним миром, это все внутреннее.

ответ

3

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

Для того, чтобы клиент знал, что что-то изменилось, вы, по сути есть только три варианта:
(а) есть список старых событий на сервере, обновления сервера, то, когда события происходят, клиенты периодически читать их и вызывать их «Уведомить», что делает Ping!
(b) каждый клиент открывает соединение с сервером и сохраняет его открытым, сервер запоминает подключения, а когда новый даже происходит, отправляет сообщение всем клиентам по уже открытым соединениям, клиенты получают сообщение и вызывают их «Уведомлять» «Это делает Пинг!
(c) клиенты отправляют на сервер регистрационное сообщение, оно содержит адрес обратного вызова/порт/etc, серверные хранилища. при возникновении события сервер считывает список и отправляет информацию на эти адреса, клиенты обрабатывают эти запросы и вызывают их уведомление в соответствии с запросом

Поскольку вы используете слова «publish-subscribe», я предполагаю, что вы имели в виду (C).

Для этой опции, касающейся уведомлений, роли клиента/сервера фактически являются отменено. В нормальном случае сервер предоставляет API клиенту, клиент подключается к нему, отправляет запрос, сервер обрабатывает его и возвращает некоторый ответ. Здесь обе стороны должны сделать то же самое. Клиентское приложение также должно выставлять на сервер вызываемый API, так что, когда происходит «событие», сервер может подключиться к API-интерфейсу клиента и отправить ему запрос с данными уведомления.

Теперь, как бы вы структурировали API - это зависит от вас.У вас может быть один метод Notify(string xmlizedOrJsonizedData), у вас могут быть параметры Notify(string infotype, datetime, data) или многие методы NotifyEmal(...) NotifyBullet(...) ... - после внедрения регистрации и бухгалтерского учета подписки вам просто понадобится сервер для вызова в api клиента с правильными данными запроса, точно так же, как клиент делает то же самое все время.

Теперь это небольшая работа, чтобы написать все это и изобретать колесо. Есть много библиотек, которые уже могут это сделать. Я посмотрел, и я ничего не нашел в документах NancyFx об этом. Вероятно, вы могли бы использовать его для создания клиентской api, как и для создания api на стороне сервера, но .. есть улов.

Клиентская сторона и серверная сторона отличаются.

Когда клиент разговаривает с сервером, есть только один сервер для отправки и прослушивания. Вы можете сделать это наивно, даже если вы хотите заблокировать пользовательский интерфейс. Когда сервер отправляет уведомления обратно, может быть 10000 клиентов. Вы даже не должны начинать писать это наивно. Зацикливание на этом множестве клиентов и ожидание до завершения может полностью заморозить ваш сервер, а если не замораживать, то причиной замедления и тайм-аутов. Кроме того, сервер находится на публике. Клиентов нет. Клиенты часто находятся за NAT, брандмауэрами и другими забавными вещами, которые передают трафик с сервера Client-> to-> Server, но могут блокировать трафик в другом направлении. Самый простой пример - блокирование портов. :80 на сервере почти всегда проходит через брандмауэры, но :80 на клиенте, вероятно, будет недоступен, и когда клиент откроет свой api на :23122, он, вероятно, не будет настроен на своих брандмауэрах/маршрутизаторах .. если вы не справитесь с этим с помощью upnp/etc.

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

Именно поэтому была изобретена вещь под названием «WebSockets». Это по существу вариант (B), о котором я говорил вначале. Это действительно стоит исследовать. Вся концепция подписки-публикации также реализуется как вызовы/ответы на сервер/клиент apis/interfaces через websocket, но это избавляет вас от многих проблем с работой и сетью.

Я нашел информацию о том, что возможно use Nancy and SignalR, так что это может быть очень хорошим началом.

+0

Я думаю, что мой вопрос имеет много двусмысленности в нем из-за того, что я не понимаю основ. Я извиняюсь об этом. Когда вы говорите клиент и сервер, клиент и сервер размещаются внутри пользователя на компьютере пользователя, он не разговаривает с внешним миром. –

+0

@JamieR: Важно, пожалуйста, добавьте это на свой вопрос, это поможет другим людям ответить более целенаправленно. i, e, это делает (C) проще и безопаснее с точки зрения сетевых проблем. Это также ограничивает количество клиентов. Это также может означать, что вы можете уйти без «базы данных подписки». Если количество клиентов невелико, и если вам также не нужны надежные долгосрочные подписки, вы можете использовать очень простой список клиентов в памяти, который упростит выполнение (C) даже вручную с нуля.Тем не менее, я советую искать библиотеку, так как «маленькие локальные системы» любят расти. – quetzalcoatl

0

Если слушатели будут находиться в одном приложении, а не удаленном сервисе, вы, вероятно, захотите использовать что-то вроде внутренней оболочки сообщения для приложения. Я знаю, что вы, возможно, не используете WPF/MVVM, но в среде MVVM light есть небольшая примерная реализация шины сообщений.

Однако для вашей конкретной цели вы можете найти пример, который не привязан к MVVM, или просто написать что-то подобное.

+0

Do у вас есть примеры, предложения о том, как написать что-то подобное? –

0

Вы можете использовать носитель .NET distributed cache as a publisher/subscriber. NCache обеспечивает такой механизм

В основном вы будете использовать приложение Начатый пользовательских событий

Регистрация Ваши события

public void OnApplicationEvent(object notifId, object data) 
{ 
    ... 
} 
_cache.CustomEvent += new CustomEventCallback(this.OnApplicationEvent); 

И стрелять те события, когда вам нужно

_cache.RaiseCustomEvent("NotificationID", DateTime.Now);