Архитектура / шаблоны для передачи активных данных в клиент-серверное приложение - PullRequest
3 голосов
/ 04 августа 2010

У меня есть сервер, который управляет сложной промышленной системой.

Нам нужно написать удаленный клиент, который сможет подключаться к серверу и «наблюдать» за его внутренним состоянием. Мне нужно потренироваться:

  • Как установить текущее состояние при подключении клиента
  • Как держать клиента в курсе изменений на сервере
  • Копируем ли мы все объекты / состояния на сервере или просто подмножество?

Мой текущий подход заключается в написании кода вручную, который отслеживает изменения каждого объекта на сервере, и отправляет их в виде сообщений клиенту. Клиент получает эти сообщения и применяет эти изменения к своей локальной модели.

Проблема в том, что это связано с большим количеством ручного кодирования, и у меня есть три класса для каждой сущности: сервер, сообщение и клиент. Даже наблюдение за изменениями состояния довольно трудоемко.

Я чувствую, что должен быть лучший, обобщенный способ достичь этого?

Между прочим, я использую технологии .net, c #, WPF и WCF

Ответы [ 2 ]

3 голосов
/ 04 августа 2010

То, что я собираюсь предложить, может быть очень трудно адаптировать к существующей системе, но я думаю, что это эффективный шаблон.Вы можете назвать это «Реплицируемая модель».

Моя идея состоит в том, что на вашем сервере есть модель, а клиент должен иметь идентичную модель.

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

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

 Hey Server, I'd like to to start replicating

сервер идет

 Here's the current snaphot and I'll be sending you all updates after that

Есть много морщин на это.Например, как вернуть синхронизацию, если сообщения потеряны.

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

Преимущество этого подхода состоит в том, что, как только вы включите механизм репликации, он практически не будет обслуживаться по мере изменения Модели.Если все классы моделей и события chnage являются сериализуемыми, тогда один и тот же код выполняется на сервере и клиенте.

2 голосов
/ 04 августа 2010

Нужно ли клиенту знать все о состоянии сервера?Я предполагаю, что некоторые вещи, происходящие на сервере, не важны и не нуждаются в мониторинге или являются слишком подробными для полного мониторинга.Поэтому клиент будет рассматривать сводную информацию о состоянии сервера, а не полную информацию обо всем.

Реплицированная модель djna - отличная идея - отдельный набор классов моделей на сервере, представляющий состояние, котороенужно поделиться с клиентом.Это будет упрощенная сводка полного внутреннего состояния сервера.

Мне интересно, сколько различных частей кода на сервере вносит изменения, о которых клиент должен знать - изменения в общей модели.Если изменения происходят из разных мест, не могли бы вы поместить упрощенный фасад поверх модели, чтобы контролировать доступ к нему?Поэтому, если все компоненты A, B, C и D необходимо внести изменения, все они должны пройти через фасад.Затем вы можете разместить логику отслеживания событий на фасаде, а не на всей модели.

Если вам нужно отслеживать много разных классов, вы можете использовать аспектно-ориентированное программирование для автоматизации добавления кода отслеживания в каждый класс. PostSharp - хороший инструмент, который может сделать это, добавляя код в ваши сборки .NET при компиляции приложения.

Это сообщение в блоге об использовании PostSharp для автоматизации отслеживания изменений с использованием интерфейса INotifyPropertyChanged.Похоже, для этого есть также плагин PostSharp с именем PropFu .

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

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

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

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

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