Комментарии 30
MsgPack вполне должен был справиться, у него единственный ньюанс при работе в Юнити — надо заранее генерить сериализаторы.
Но сложный пример, который будет, далее...И где? То, что в разделе «Тест»?
… не осилил… binary formatter.Так указано же в чем ошибка.
SerializationException: Type TestS+TestC1 in assembly Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null is not marked as serializable.
«Самое логичное решение — это использовать бинарный протокол»
Почему не json? Про размер пока не говорим.
Почему не json? Про размер пока не говорим.
Ну и переименовывать поля при мапинге на типы — размер получается соизмеримым с бинарным, в том числе по скорости работы, поддержке произвольных типов, отсутствию необходимости схемы на обоих концах.
При приличном потоке данных на сериализацию, количество строк подлежащих утилизации зашкаливает.
Не все бинарные данные помещаются в текстовый формат. Про base64 пока не говорим.
Зачем использовать json при обмене между unity и photon? Можно его без всяких проблем перехватить. Бинарный же нужно еще декодировать. Любой при чем. Потом как решить проблему со сложными типами? Например объекты типа инвентарь?
Перехватить — можно, и что из этого следует? Вы думаете, что кодирование в двоичный вид как-то шифрует данные? Ну и да, если принципиальна двоичность, существует BSON
Потом как решить проблему со сложными типами?
В чем проблема типов любой сложности? Это всего лишь KV-пары, корректный мапинг организуется достаточно просто через атрибуты (как, например, было сделано для DataContract / DataMember в SimpleJson).
Тест для простого примера, для реального примера . Json не сериализует поля типа интерфейс и абстрактный класс. Для этого нужен бубен, пример И наконец, как решать вопрос со сборкой? переименовать? ведь на клиенте и сервере классы хоть и одинаковые, но сборки разные.
Json не сериализует поля типа интерфейс и абстрактный класс. Для этого нужен бубен
Добавить в сериализатор дополнительные условия (пример библиотеки в сорцах я привел выше, один файлик с кучей условных компиляций под разные рантаймы). Это явно быстрее и правильнее чем писать полностью независимый и потенциально нестабильный костыль. Ну и симулировать по сети аналог ремоутинга с проксированием классов — это зло. Данные должны быть максимально простыми. Не должно быть никаких интерфейсов и т.п, с ними есть проблемы с AOT-компиляцией сейчас и будут в будущем при использовании IL2CPP, ибо часть типов выводится в JIT в рантайме. Геймдев — это не enterprise way, тут нужно отказываться от промежуточных абстракций в угоду скорости и переносимости.
как решать вопрос со сборкой? переименовать?
Как связаны сборки на сервере / клиенте? Таки аналог ремоутинга и common-сборки? json хорош тем, что не требует схем. Как дальше будут обслуживаться данные — это проблемы разработчика. Нужно максимально абстрагировать сетевые данные от любых типов в клиенте / сервере — уйдут все проблемы с любыми библиотеками типа протобуфа и т.п.
Связь через ссылки на классы. По заданным требованиям, сериализовать сложные составные объекты справился только протобуф и стандартный сериализатор. «Данные должны быть максимально простыми», куда проще чем набор байтов.
Типы должны быть простыми — числа, строки, массивы простых типов. Использование кода и на клиенте и на сервере сильно привязывает к конкретному серверу, от этого лучше сразу избавляться, чтобы потом без проблем обеспечивать коннект хоть к photon, хоть к smartfox, хоть к кастомному решению на nodejs. Использование кастомных типов так же допустимо, но следует помнить о том, что в них будут сериализованы тоже только простые типы (ну и вложенные кастомные, рекурсивно). Сервер и клиент должны быть максимально разнесены, сериализация без схемы позволяет это сделать.
А для чешл тогда были придуманы protobuf message box fb protocol и другие? Очень смутно представляется перескок на другой сервер (например с фотона на sfx еще ладно. они схожи. а вот на другой). В любом случае это не быстро, да и зачем.
Для того и были придуманы, чтобы абстрагироваться от конкретной реализации и платформы и работать исключительно с переносимыми типами. Нужно стремиться к этому. Как только заработает протобуф — заработает все остальное и это будет означать, что все сделано правильно.
В этом и идея чтобы минимизировать дублирование кода. Максимум common для ключей.
К серверу привязывает только протокол общения. Но не кто же не мешает использовать массив байтов. Или строку. (Но строки то не дешевые, выбор байтового массива в этом случае более актуален) Если ява, придется продублировать свой сериализатор, тоже и для других языков. Что собвственно тот же message pack и сделал. Сложно представить систему, для msgpak которой не реализован.
К серверу привязывает только протокол общения. Но не кто же не мешает использовать массив байтов. Или строку. (Но строки то не дешевые, выбор байтового массива в этом случае более актуален) Если ява, придется продублировать свой сериализатор, тоже и для других языков. Что собвственно тот же message pack и сделал. Сложно представить систему, для msgpak которой не реализован.
dot.net
вот это, пожалуй, уже самое дно
Самое логичное решение — это использовать бинарный протокол
Самое логичное решение — использовать движок, изначально приспособленный для работы с сетью, не? Примитивную репликацию полей вы допустим на коленке собрали, но вот репликацию движения объектов (плавного, с экстраполяцией, без roundtrip-задержек на инициирующем клиенте, с корректировкой при лагах), например, так задешево сделать уже не получится.
А потом понадобятся фичи типа «а вот эти поля надо реплицировать только игроку, которому принадлежит этот объект, а остальным ни-ни», «а вот по факту обновления этого поля надо на реплике какую-то кастомную логику выполнить» и т.д.
У нас, когда делали прототип игры на Unity, получилось все примерно как у вас — Unity, Photon и горка костылей поверх всего этого. Но, слава ЛММ, это был только прототип, исходники которого после завершения торжественно распечатали и сожгли.
Задача именно серелизовать объекты. Поля и так поделены на классы. И у каждого игрока своя модель. На сервере модели сереализуются с бд только при включении и выключении сервера. А так они всегда активны, зашел игрок. Его конектит к его модели, та шлет события, мол кто-то куда то пошел или чет построил. Нужно знать о втором игроке, принцип тот же.
А на что прешли вместо Unity?
Thrift или Avro испытывали?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Binary serialization in Unity3d