Запуск графического отображения на нескольких системах с синхронизацией - PullRequest
2 голосов
/ 14 сентября 2009

У меня есть несколько систем в локальной сети, на которых выполняется процедура синхронизированного отображения. Например, подумайте о линии хора. Программа, которую они запускали, исправлена. У меня каждый «клиент» загружает всю подпрограмму, а затем связывается с центральным «сервером» в фиксированных точках подпрограммы для синхронизации. Сама процедура рутинна, возможно, с 20 возможными инструкциями.

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

Это все закодировано в C # .Net.

Дисплей клиента представляет собой приложение Windows Forms. Сервер принимает соединения TCP, а затем обслуживает их циклически, сохраняя основные часы происходящего. Клиенты посылают сигнал, который говорит: «Я достиг точки синхронизации 32» (или 19, или 5, или что-то еще) и ждет подтверждения от сервера, а затем продолжает работу. Или сервер может сказать «Нет, вам нужно начать с точки синхронизации 15».

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

Затем Спецификация изменилась.

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

Мой инструментарий включает в себя все, что входит в стандартный набор инструментов .Net 3.5. Установка нового программного обеспечения - трудная задача, так как может быть задействовано очень много систем (клиентов).

Я ищу предложения по синхронизации клиентов (какая-то система блокировки? UDP? Broadcast?), Распространение "танцевальной программы", что-нибудь, что может сделать это проще, чем традиционная договоренность между клиентом и сервером TCP.

Имейте в виду, что существуют также ограничения по времени / скорости. Я мог бы поместить танцевальную программу в сетевую базу данных, но мне пришлось бы достаточно быстро вводить инструкции, и было бы много читателей, использующих довольно толстый протокол (DBI, SqlClient и т. Д.), Чтобы получить немного текста. Это кажется слишком сложным. И мне все еще нужно что-то, чтобы они все отображались синхронно.

Предложения? Мнения? Дикая спекуляция? Примеры кода?

PS: Ответы не могут быть помечены как «правильные» (поскольку это не «правильный» ответ), но +1 голос за хорошие предложения наверняка.

1 Ответ

1 голос
/ 14 сентября 2009

Я сделал нечто подобное (довольно давно) с синхронизацией банка из 4 дисплеев, каждый из которых запускается одной системой, и получая сообщения от центрального сервера.

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

Затем сервер отправит всю серию команд для этой серии на эту одну машину.

Затем эта машина использовала UDP для широковещательной передачи инструкций в режиме реального времени на каждую из других машин (19 других клиентов в своей локальной сети), чтобы поддерживать актуальность своих дисплеев. Здесь мы использовали UDP по нескольким причинам - были задействованы более низкие издержки, что помогло снизить общее использование ресурсов. Кроме того, поскольку вы обновляете в режиме реального времени, если один или два «кадра» были не синхронизированы, это никогда не было заметно, по крайней мере, недостаточно заметно для наших целей (наличие человека, сидящего и взаимодействующего с системой).

Ключевым моментом для этой плавной работы, однако, является наличие интеллектуальных средств связи между главным сервером и «главным» компьютером - вы хотите поддерживать пропускную способность как можно ниже. В случае, подобном вашему, я, вероятно, придумал бы один двоичный двоичный объект с текущими инструкциями, установленными для 20 машин, в его наименьшей форме. (Может быть, что-то вроде 20 байтов или 40 байтов, если вам это нужно, и т. Д.). Затем «главный» компьютер будет беспокоиться о том, чтобы перевести это на другие 19 машин и на себя.

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

«Главный» сервер самый хитрый. В нашей реализации мы фактически имели тот же клиентский код, что и остальные 19 (как отдельный процесс), и один процесс «перевода», который брал большой двоичный объект, разбивал его на 20 частей и передавал их. Его было довольно просто написать, и он работал очень хорошо.

...