Создание приложения для рисования совместной доски
У меня есть своя собственная программа для рисования с различными "инструментами для рисования", такими как Pen, Eraser, Rectangle, Circle, Select, Text и т. Д.
Это сделано с помощью Python и wxPython. Каждый инструмент, упомянутый выше, является классом, который имеет полиморфные методы, такие как left_down(), mouse_motion(), hit_test() и т. Д. Программа управляет списком всех нарисованных фигур - когда пользователь нарисовал форму, он добавляется к списку. Это также используется для управления операциями отмены / возврата.
Итак, у меня есть приличная кодовая база, в которую я могу подключить совместное рисование. Каждую фигуру можно изменить, чтобы узнать ее владельца - пользователя, который ее нарисовал, и разрешить выполнение операций удаления / перемещения / изменения масштаба только для фигур, принадлежащих одному человеку.
Мне просто интересно, как лучше это развить. Один человек в "сеансе" должен будет выступать в роли сервера, у меня нет денег, чтобы предлагать бесплатные центральные серверы. Каким-то образом пользователям потребуется способ подключения к серверам, то есть какой-то браузер "обнаружения серверов"... или что-то в этом роде. Как транслировать изменения, внесенные в приложение? Рисование в реальном времени и передача сообщения о каждом событии движения мыши будет дорогостоящим с точки зрения производительности, и чем больше пользователей в данный момент времени, тем хуже.
Любые идеи приветствуются, я не слишком уверен, с чего начать разработку (или даже как это проверить)
1 ответ
Создание любого инструмента / игры для совместной работы в реальном времени сводится к эффективной синхронизации изменений в минимальной общей структуре данных между клиентами. Пропускная способность сети является узким местом. Отправляйте только информацию, абсолютно необходимую для синхронизации общих данных. Вы на правильном пути, сохраняя фигуры вместо отдельных пикселей. Однако фигуры не должны обрабатывать события мыши. Как вы заметили, трансляция событий мыши быстро насыщает пропускную способность сети! Вместо этого передайте дельты о том, как формы изменяются событиями мыши. Например, вместо отправки mouse_motion() отправьте конечную позицию [x,y] после перемещения фигуры.
Я предлагаю разделить вашу программу для рисования на серверную и клиентскую части. Сервер сохраняет официальную версию общих данных. Клиент никогда не манипулирует общей структурой данных напрямую; он только отправляет сетевые сообщения на сервер. Это может показаться глупым, когда и клиент, и сервер находятся в одном и том же процессе / ПК, но есть несколько веских причин:
- Путь общего кода для однопользовательского и многопользовательского
- Сетевые издержки между клиентом и сервером в одном и том же процессе близки к нулю при использовании локальных сокетов
Кроме того, редактирование не обязательно должно быть ограничено владельцем этой фигуры. Поскольку сервер является конечным органом, он разрешает любые конфликты, когда два человека одновременно получают одну и ту же форму и отправляют результаты обратно клиентам. (Отмена становится немного хитрой, хотя.)
Хотя централизованный сервер лучше всего подходит для обнаружения сети, клиенты могут использовать другие методы для поиска сервера:
- Отправка или прослушивание сетевых широковещательных пакетов.
- Подключайтесь напрямую через IP-адрес. (IP-адрес сервера должен быть сообщен с помощью других средств: чат, мобильный телефон, выкрикивание по комнате, почтовый голубь,...)
Наконец, посмотрите, как спроектированы другие многопользовательские приложения. Вот некоторые примеры:
- Zoidcom Библиотека многопользовательских игр (C++). Большая часть этого ответа основана на информации из документации Zoidcom. Есть даже примеры программ, которые демонстрируют обнаружение сервера через сетевое вещание.
- Алгоритм оперативного преобразования позади Wave, Google Docs. ( обсуждение статьи на Hacker News)
- Etherpad Открытый в режиме реального времени совместный текстовый редактор.
- Исходная многопользовательская сеть Объясняет, как устроен FPS, такой как HAlf-life. Проникает в уловки для уменьшения задержки / задержки.
- Google Wave (видимо, документация все еще довольно скудная...)