Как синхронизировать один и тот же объект на стороне клиента и сервера в клиент-серверном приложении? Хороша ли для этой работы структура небольших сообщений? - PullRequest
1 голос
/ 02 января 2009

Я делаю игровой движок на с ++ и python. Я использую OGRE для 3D-рендеринга, OpenAL для звука, ODE для физики, OIS для ввода, HawkNL для работы в сети и boost.python для встроенного интерпретатора Python. Каждая подсистема (библиотека) обернута менеджером классов, и каждый менеджер является одиночным. Теперь у меня есть класс - Object - это может быть любой видимый объект в игровом мире. Это какая-то смесь, объект имеет графическое представление (сущность) и представление в физическом симуляторе (твердое тело). Эти два наиболее важны здесь. Класс Object - это просто чистый абстрактный базовый класс - интерфейс. Я решил реализовать Object на стороне клиента как ObjectClientSide - эта реализация имеет сущность, а на стороне сервера как ObjectServerSide - эта реализация имеет твердое тело. Физический симулятор работает только на сервере, а рендеринг - только на клиенте. Объект может существовать только тогда, когда обе реализации работают вместе. Каждый объект имеет уникальный идентификатор, и оба экземпляра одного и того же объекта на стороне клиента и сервера имеют одинаковый идентификатор.

Итак, после этой краткой истории мой первый вопрос: хорош ли этот дизайн? Как я могу сделать это лучше? И главный вопрос: как мне синхронизировать эти объекты?

Далее, обе реализации имеют один и тот же интерфейс, но часть его реализована на стороне сервера, а часть на стороне клиента. Так, например, если игрок хочет продвинуть своего персонажа, он должен отправить запрос на объект на сервере. Затем сервер вносит изменения в моделирование и отправляет обновленную позицию клиенту. По этой причине я создал небольшую структуру сообщений. Существует класс Message, Router, Rule и правила, унаследованные от Rule. Когда приходит сообщение, маршрутизатор проверяет его на соответствие правилам и отправляет его по назначению. Поэтому, когда я вызываю myObjectInstanceOnClientSide-> setPosition (x, y, z), этот объект создает сообщение, его содержимое - это функция и параметры, а назначение - объект с тем же идентификатором на сервере. Когда объект с тем же идентификатором на стороне сервера получает это сообщение, он вызывает эту функцию с заданными аргументами. Таким образом, когда функция не может быть реализована на одной стороне, она создает сообщение и отправляет его объекту на другой стороне. Я думаю, что это может быть очень полезно в сценариях. Сценарии могут быть очень чистыми, если, например, сценарий должен включать анимацию на клиентах, мне нужно вызывать эту функцию только на локальном объекте сервера - остальное в фоновом режиме.

Так это нормально? Я ошибаюсь по этому поводу? Это общее решение?

1 Ответ

7 голосов
/ 02 января 2009

Звучит так, будто вы посылаете много маленьких сообщений. Заголовки UDP и IP добавят 28 байтов служебной информации (20 байтов для заголовка IPv4 или 40 байтов для IPv6 плюс 8 байтов для заголовка UDP). Итак, Я бы предложил объединить несколько сообщений для отправки с периоидной скоростью.

Вы также можете прочитать эти другие вопросы и ответы:

Я добавил кучу полезных ссылок на DevMaster.net Wiki лет назад, которые все еще актуальны:

Я бы предложил начать читать блог Гленна Фидлера . Он проделал невероятную работу с сетевой физикой, включая недавний релиз Mercenaries 2 . Он начал серию статей под названием Сеть для игровых программистов .

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