Предисловие
В определённый момент при разработке игр и крупных приложений придётся столкнуться с такой частью как сеть. В моём случае, при разработке онлайн шутера, это было очевидно в самом начале. И естественно, во время любой разработки подобных проектов, у многих возникают проблемы. У меня они возникли не сразу, а только после того, как я занялся базой данных. О том что за проблемы и как их решить — далее…
База данных
Для сохранения данных мы решили использовать DynamoDB, key-value базу данных от Amazon. Суть БД достаточно проста, выбрана была из-за скорости работы и дешевизны.
Проблема 1
Одна из первых проблем подкралась достаточно быстро, это асинхронность. Асинхронность — свойство исполняемого кода, когда не происходит полного ожидания выполнения функции, то есть её функционал происходит в фоновом режиме.
DynamoDB не имеет синхронных методов получения данных для Unity, а для .NET в целом — имеет. С одной стороны — это логично, не будем же мы полностью останавливать поток и рендеринг и весь сервер, чтобы дождаться данных об игроке, с другой — можно было бы и оставить синхронные методы, сам бы понял в чём проблема и исправил.
Вторая часть этой проблемы — в нашем фреймворке для серверной части не было асинхронных методов получения данных, т.к. там использовалась локальная база данных. В итоге пришлось добавить асинхронность, благо это было не так сложно. Если бы это не было сделано, то всё бы работало крайне некорректно.
Проблема 2
Далее возникла проблема подключения. Качество документации оставляет желать лучшего, но проблему решил. Суть заключалась в том, чтобы предоставить доступ к БД определённому «нечто», имеющему ключ. Сначала пробовал решить это через AWS Cognito, но это было совершенно не то. Для получения пароля для доступа к DynamoDB нужно создать ещё один аккаунт на Amazon. Это аккаунт IAM User, он принадлежит главному аккаунту, через который можно дать привилегии. Важный момент — во время регистрации такого аккаунта, секретный ключ доступа будет предоставлен единожды. Далее этот ключ никак нельзя будет получить, даже в главном аккаунте. Берегите этот ключ. В самом коде его нужно будет использовать для создания класса клиента, при помощи вот такого конструктора:
AmazonDynamoDBClient
(
awsAccessKey, // просто ключ доступа
awsSecretAccessKey, // ключ доступа, который лучше не терять
// регион, в котором находится БД
RegionEndpoint.GetBySystemName(RegionEndpoint.EUCentral1.SystemName)
);
Это решит все проблемы с подключением и у вас появится уникальный защищённый доступ к DynamoDB. У меня поиск этого решения отнял кучу нервов и времени.
Проблема 3
Ну и самое весёлое — получение данных. DynamoDB для .NET имеет две системы — Object Persistance Model и Document Model. Я пытался получить данные в виде объектной модели. И тут документация сильно всё запутала. Для нормального получения данных у свойств нужного класса нужно лишь указывать атрибуты (атрибуты ключей, атрибуты свойств), ну и указать, атрибут класса (к какой таблице он относится). С этим всё было понятно, но проблема была с вложенными классами. В примерах для .NET есть только получение классов, состоящих из простых свойств и списков простых свойств (int, float, string). А мне нужно было получать достаточно большой объект — профиль игрока, который состоял из инвентаря, состоящего из названий орудий и улучшений к ним, и прочих вложенных классов.
Решение пришло само собой. Сначала я почитал вот это, сделал простой конвертер в json, но забыл указать атрибут. В итоге оказалось, что DynamoDB SDK сам прекрасно конвертирует всё в свой формат и отправляет в базу данных. Нужно лишь указывать атрибуты на главном классе, вложенные будут конвертированы самостоятельно.
Конвертер я убрал, всё работало без него, но сколько я не искал, нигде так и не нашёл упоминаний о вложенных классах (даже когда всё работало).
На этом всё, читайте доки и думайте сами, если их недостаточно.