Ok,
это более общий вопрос "уродливые твари в углу". Планирую начать проект на WCF и PRISM. Я какое-то время играл с PRISM, знаю, и должен сказать, мне это нравится. Прочная основа для приложений с хорошими возможностями для роста.
Теперь я хочу включить WCF и создать распределенное приложение, одна часть которого находится на сервере, а две - на клиентах. Это может быть даже одна и та же машина или нет, в зависимости от сценария.
Моя идея теперь состоит в том, чтобы взять концепцию события из PRISM и расширить ее «по сети» с помощью WCF и обратных вызовов, как описано здесь Пример обратного вызова WCF AlarmClock.
Я создал небольшую картинку, чтобы проиллюстрировать идею (в основном для себя), возможно, это проясняет ситуацию:
Серые стрелки означают «использование библиотеки». WCF-Event-Base означает обычные события PRISM, где метод публикации вызывается «по сети».
На ум приходят несколько вопросов:
- Есть ли какие-нибудь известные примеры таких вещей?
- Что будет лучшим способом «поднять» события по сети?
- Любые возможные проблемы с этой концепцией (упомянутые ранее уродливые твари)
Что касается второго вопроса, в настоящее время я думаю о возбуждении событий с использованием строки (тип конкретного события, которое я хочу вызвать) и полезной нагрузки в качестве аргумента. Что-то вроде public void RaiseEvent(string eventType, object eventPayload){}
. Полезная нагрузка должна быть сериализуемой, возможно, я даже включу хэш-проверку. (Это означает, что если я подниму, например, событие с изображением в качестве аргумента 10 раз, я передаю изображение только один раз, а затем использую хеш, чтобы сервер использовал буфер при публикации) ...
Хорошо, я думаю, вы уловили идею. Эта «штука» должна вести себя как одно гигантское приложение, используя своего рода WCF_EventAggregator вместо обычного PRISM IEventAggregato r. (вау, пока я писал, у меня возникла идея «просто» расширить IEventAggregator, надо подумать об этом) ...
Зачем я это пишу? Ну, в основном для обратной связи и для сортировки своих мыслей. Так что комментарии приветствуются, возможно, мне следует быть «осторожным»?
Крис
[РЕДАКТИРОВАТЬ]
Распределение клиентов
Количество клиентов должно быть неопределенным, сервер не должен знать клиентов. Сам сервер может быть клиентом для себя, вызывая строго типизированные события PRISM в других частях исходного кода.
Основное различие между «клиентом» и «сервером» - это фактическая реализация соединителя WCF_PRISM, см. Следующую главу ...
Поднятие клиентского события (функция PRISM)
В PRISM, чтобы вызывать простые события, вам даже НЕ нужна ссылка на интерфейс службы. IEventAggregator можно получить с помощью внедрения зависимостей, предоставив экземпляр желаемого события (например, WeatherChangedEvent). Это событие можно вызвать, просто вызвав eventInstance.Publish (23), потому что событие реализовано как public class WeatherChangedEvent : CompositePresentationEvent<int>
WCF - соединитель PRISM
Подписка на события - это так же просто, как создание событий. Каждый модуль может подписаться на события, используя один и тот же метод, получая ссылку и используя Подписка для присоединения к этому событию.
Вот где должно произойти «волшебство». Клиенты будут включать в себя модуль призмы, отвечающий за подключение событий PRISM к «отправкам сообщений wcf». Он будет в основном подписываться на все доступные события в решении (все они в любом случае определены в модуле инфраструктуры) и отправлять сообщение WCF в случае возникновения события.
Разница между СЕРВЕРОМ и КЛИЕНТОМ заключается в реализации этого модуля. Должна быть небольшая разница по двум причинам.
- Параметры настройки WCF
- Поток событий для предотвращения бесконечного цикла
Поток событий будет (пример)
- Клиент получает ссылку на WeatherChangedEvent
- wChanged.Publish (27) -> обычное инициирование события PRISM
- Модуль WCF_PRISM подписан на событие и
- отправить это событие на сервер
- Сервер внутренне получает экземпляр WeatherChangedEvent и публикует
- Сервер перезванивает всем клиентам, вызывающим их WeatherChangedEvent
Открытые точки
Очевидный момент - предотвращение петли. Если сервер вызовет событие во ВСЕХ клиентах, клиенты обратятся к серверу, снова вызовут событие и так далее ... Таким образом, должна быть разница между событием, вызванным локально (что означает, что я должен отправить его на сервер) и «событие, вызванное сервером», что означает, что мне не нужно отправлять его на сервер.
Кроме того, если клиент сам инициировал событие, его не нужно вызывать сервером, потому что событие уже было инициировано (в самом клиенте, пункт 2).
Все это особое поведение будет инкапсулировано в модуле создания событий WCF, невидимым для остальной части приложения. Я должен подумать о том, «как узнать, что событие уже опубликовано», возможно, GUID или что-то в этом роде было бы хорошей идеей.
А теперь второй большой вопрос, что я имел в виду, когда раньше рассказывал о «струнах». Я не хочу писать новое определение интерфейса службы каждый раз, когда добавляю событие. Большинство событий в PRISM определяются одной строкой, особенно во время разработки я не хочу обновлять WCF_Event_Raising_Module каждый раз, когда добавляю событие.
Я думал об отправке событий напрямую при вызове WCF, например. используя функцию с подписью вроде:
public void RaiseEvent(EventBase e, object[] args)
Проблема в том, что я действительно не знаю, смогу ли я так просто сериализовать события PRISM. Все они являются производными от EventBase, но я должен это проверить ... По этой причине у меня возникла идея использовать тип (как строку), потому что я знаю, что сервер разделяет модуль инфраструктуры и может получить свой собственный экземпляр события (не нужно пересылать по сети, только аргумент)
Пока что я оставлю вопрос открытым, чтобы получить больше отзывов. Главное новое «понимание», которое я только что получил: нужно подумать о проблеме рекурсии / бесконечного цикла.
Кстати. если кого-то совершенно сбивают с толку все эти разговоры о событиях, попробуйте PRISM. Вам понравится, даже если вы используете только DI и события (например, RegionManager не мой любимый)
Крис
[КОНЕЦ РЕДАКТИРОВАНИЯ 1]