Photon Логика (операции, события)

Photon Логика (операции, события)

Сообщение DavilSin 21 ноя 2011, 13:14

Продолжаю ковырять фотон И не могу придумать как правильно делается следующие Имеем клас PhotonServer унаследованный от ApplicationBase
Синтаксис:
Используется csharp
 class PhotonServer : ApplicationBase
    {
        #region Overload of AplicationBase
        protected override PeerBase CreatePeer(InitRequest initRequest)
        {
            return new UnityClient(initRequest.Protocol, initRequest.PhotonPeer);
        }

        protected override void Setup()
        {
            var file = new FileInfo(Path.Combine(BinaryPath, "log4net.config"));
            if (file.Exists)
            {
                LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
                XmlConfigurator.ConfigureAndWatch(file);
            }
        }

        protected override void TearDown()
        {
           
        }
        #endregion
    }
 



И класс UnityClient унаследованный от PeerBase (представлено часть кода)

Синтаксис:
Используется csharp
public class UnityClient : PeerBase
    {
        private readonly ILogger log = LogManager.GetCurrentClassLogger();

        public UnityClient(IRpcProtocol protocol, IPhotonPeer peer)
            : base(protocol, peer)
        {
            log.Debug("Connected from " + peer.GetRemoteIP());
        }
        protected override void OnDisconnect()
        {
            log.Debug("Client disconnected");
        }

        protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch(operationRequest.OperationCode)
            {
                case 1:
                        if (operationRequest.Parameters.ContainsKey(1))
                        {
                            log.Debug("Recived 123 " + operationRequest.Parameters[1]);
                            OperationResponse response = new OperationResponse(operationRequest.OperationCode);
                            response.Parameters = new Dictionary<byte, object> { { 1, "Response recived" } };
                            SendOperationResponse(response, sendParameters);
                            Flush();
                        }        
                        break;
                case 2:
                        if (operationRequest.Parameters.ContainsKey(1))
 


Тоесть я отлавливаю OnOperationRequest и через switch(operationRequest.OperationCode) узнаю что пришло и что делать дальше
Но сразу возникает Вопрос а если ответов от клиента нужно учитывать сотни, то нужно делать сто case или это как то можно по другому реализовать? Покажите или расскажите как это правильно делается? Какие есть способы еще?
Изображение
Аватара пользователя
DavilSin
UNIт
 
Сообщения: 74
Зарегистрирован: 16 апр 2011, 11:10

Re: Photon Логика (операции, события)

Сообщение Груберк 21 ноя 2011, 16:21

Можно еще рефлекшеном делать. Функциям обработчикам давать атрибуты в которых указывать номера обрабатываемых ими операций, а потом запустить менеджер и радоваться результату. Подробнее увидишь если покопаешься в исходниках MMO сервера.
Но мне кажется, что вряд ли у тебя даже сотня case'ов наберется то в игре...
Вообще способ со switch он намного проще отлаживается и в понимании прозрачнее, так что советую "не оптимизировать то, что у тебя не тормозит". Если нужно будет, то одно в другое переделать, как два пальца ... (Развернешь свой свитч, наклепаешь атрибутов, делов на одну ночь)
Груберк
UNIт
 
Сообщения: 133
Зарегистрирован: 05 июл 2011, 13:26

Re: Photon Логика (операции, события)

Сообщение DavilSin 22 ноя 2011, 09:42

(3A4OT)

Уже ситуация проясняется
Груберк писал(а):Можно еще рефлекшеном делать. Функциям обработчикам давать атрибуты в которых указывать номера обрабатываемых ими операций, а потом запустить менеджер и радоваться результату. Подробнее увидишь если покопаешься в исходниках MMO сервера.


Можно маленький примерчик плиз или тыкнете носос в файлик ММО.Demo
И еще вопросик что такое рефлекшен?
Изображение
Аватара пользователя
DavilSin
UNIт
 
Сообщения: 74
Зарегистрирован: 16 апр 2011, 11:10

Re: Photon Логика (операции, события)

Сообщение Груберк 22 ноя 2011, 20:20

откройте любой файл в src-server\Mmo\Photon.MmoDemo.Server\Operations
там вы заметите, что перед функциями обработчиками стоят атрибуты, например:

Синтаксис:
Используется csharp
 /// <summary>
        /// Gets or sets the id of the new <see cref="InterestArea"/>.
        /// </summary>
        [RequestParameter(Code = (short)ParameterCode.InterestAreaId)]
        [ResponseParameter(Code = (short)ParameterCode.InterestAreaId)]
        public byte InterestAreaId { get; set; }


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

Далее заходим в MmoPeer.cs и замечаем:

Синтаксис:
Используется csharp
#if OperationDispatcher
        private static readonly OperationMethodInfoCache operations = new OperationMethodInfoCache();

        private readonly OperationDispatcher dispatcher;

        static MmoPeer()
        {
            operations = new OperationMethodInfoCache();
               
            try
            {
                operations.RegisterOperations(typeof(MmoPeer));
                operations.RegisterOperations(typeof(CounterOperations));
            }
            catch (Exception e)
            {
                ErrorHandler.OnUnexpectedException(operations, e);
            }
        }
#endif


Теперь вспомним, что же такое в C# статический конструктор класса? А это такая штука, которая вызывается всего один раз в жизни класса в тот момент, когда впервые создается объект этого класса, т.е. по сути инициализатор какого-то синглтонного функционала. Тут же мы видим, что данный эффект проявляется под эффектом OperationDispatcher. Читаем дальше, разбираемся в смысле атрибутов и эффекте рефлексии... И эврика!

Если мы пометили наши обработчики событий определенными метками (атрибутами), то мы можем с помощью рефлексии выдергивать эти методы в программе в режиме RunTime! Невероятно, учитывая то, что мы можем подсовывать, через интерфейс IPeer, определенные модели поведения (Игрок подключился но не авторизовался, Игрок в лобби, Игрок в игре), далее в определении модели поведения назначать атрибуты нужным нам функциям обработки и скармливать это серверу, а он будет автоматически сопоставлять таблицу кешированных атрибутов-каллбеков (рефлексия очень дорогая штука, поэтому чем вызывать ее по 100 раз, лучше запомнить нужный каллбек, что по сути тот же switch-case, только спрятанный от ваших глаз) и вызывать нужный каллбек в данной модели поведения.

На самом деле очень мощная технология именно в архитектурном плане. Но честно говоря, если ваш практический проект это сетевые гонки для 4х человек с простеньким лобби, то всяд ли вам понадобятся все эти навороты... Проще говоря если ваша "модель" игрока может путешествовать по разным моделям поведения (например у вас шутер/стратегия/пазл все в одном на одном игровом поле) то технология сэкономит вашему напарнике нервные клетки, избавив его от ваших "макаронов" в коде. Иначе вы просто попытаетесь забить гвоздь экскаватором.
Груберк
UNIт
 
Сообщения: 133
Зарегистрирован: 05 июл 2011, 13:26

Re: Photon Логика (операции, события)

Сообщение DavilSin 28 ноя 2011, 08:30

(3A4OT)

Спасибо большое направление получил. Если б можно было на форуме ставить репутацию наклацал бы очков 100 \:D/

А теперь для смеха. Убил сутки пока понял что речь в примере идет о версии фотона 2.6 фотона =)) Теперь ковыряю мануалы и примеры для этой версии Когда разберусь попробую уже с новыми знаниями попробовать на фотоне третей версии
Изображение
Аватара пользователя
DavilSin
UNIт
 
Сообщения: 74
Зарегистрирован: 16 апр 2011, 11:10

Re: Photon Логика (операции, события)

Сообщение Груберк 29 ноя 2011, 07:37

Ну какая версия на компе была, там и накопипастил :)

Вообще конечно кода у вас при 100 пакетах будет не меньше. Представляете 99 атрибутов у callback'a "сброс" в модели поведения "игрок подключился, но не авторизовался" (и 1 атрибут у callback'a "авторизоваться" :) )?

Но сам факт того, что в обработчике каждого пакета не прийдется писать проверку на состояние в котором находится игрок ("авторизовался" или нет, а то стремно обрабатывать пакеты чата от того, кто еще не авторизовался) конечно по уменьшит головной боли в крупном проекте с разными состояниями игрока. Вобщем как я выше и говорил...
Груберк
UNIт
 
Сообщения: 133
Зарегистрирован: 05 июл 2011, 13:26

Re: Photon Логика (операции, события)

Сообщение Woolf 12 янв 2012, 13:18

Груберк писал(а):Ну какая версия на компе была, там и накопипастил :)

Вообще конечно кода у вас при 100 пакетах будет не меньше. Представляете 99 атрибутов у callback'a "сброс" в модели поведения "игрок подключился, но не авторизовался" (и 1 атрибут у callback'a "авторизоваться" :) )?

Но сам факт того, что в обработчике каждого пакета не прийдется писать проверку на состояние в котором находится игрок ("авторизовался" или нет, а то стремно обрабатывать пакеты чата от того, кто еще не авторизовался) конечно по уменьшит головной боли в крупном проекте с разными состояниями игрока. Вобщем как я выше и говорил...


Извините за некропостинг )) А зачем обрабатывать пакеты от того, кто не авторизовался? Перед switch делаете проверочку - если это пакет от неавторизованного игрока И это не авторизация - пшёл вон.
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Photon Логика (операции, события)

Сообщение Груберк 12 янв 2012, 15:42

В каждом обработчике пакета проверять авторизовался ли игрок, кошерный ли сегодня четверг и какой сейчас месяц по календарю майа?
Или заставить обработчик пакета обрабатывать пакет, а все вышеуказанные проверки отдать системе рангом выше, которая и будет из массы обработчиков пакетов подбирать те обработчики, которые нужно использовать в кошерный четверг.

А теперь представьте, что у вас 30 видов пакетов (30 обработчиков) и вы решили, что четверги не бывают кошерными, кошерными бывают субботы. Вы начинаете во всех 30 обработчиках менять четверги на субботы и забываете это сделать в 24 обработчике (жена отвлекла с этим гребаным сексом, чего им неймется-то?). И тут вдруг Иван, ученик 9 класса средней школы номер N обнаруживает, что может жрать-таки свинину по субботам из-за ошибки в 24 обработчике! Не сильно ведь приятно, да?
Груберк
UNIт
 
Сообщения: 133
Зарегистрирован: 05 июл 2011, 13:26

Re: Photon Логика (операции, события)

Сообщение beatlecore 19 дек 2013, 04:30

Груберк писал(а):В каждом обработчике пакета проверять авторизовался ли игрок, кошерный ли сегодня четверг и какой сейчас месяц по календарю майа?
Или заставить обработчик пакета обрабатывать пакет, а все вышеуказанные проверки отдать системе рангом выше, которая и будет из массы обработчиков пакетов подбирать те обработчики, которые нужно использовать в кошерный четверг.


не судьба сделать префиксы к пакетам? 1байта хватит с головой для распределения авторизационных, игровых и прочих пакетов, на момент подключения игрока проверять только авторизационные пакеты, по сути sizeInfo байта 4 и 1 байт в префиксе пакета, остальные игнорить, если игрок прошел авторизацию, вешать на него флаг "авторизованный" и так далее, все равно сайзинфо для каждого пакета проверяется, все зависит от организации пакета, все таки, если не прав, поправьте, в фотоне как-то типа того сделано

и еще по теме можно почитать это, но там на плюсах увы, хотя логика описана довольно неплохо, если не хочется писать все с нуля, в (c#) есть такая штука как .NET Framework Remoting, что-то похожее, но я глубоко не копал
Аватара пользователя
beatlecore
Старожил
 
Сообщения: 964
Зарегистрирован: 05 фев 2013, 21:26
Откуда: Sun Crimea

Re: Photon Логика (операции, события)

Сообщение afrokick 25 дек 2013, 13:50

Есть еще такая штука, называется SetCurrentOperationHandler(IOperationHandler handler);

В каком-то примере используется такой подход.

Принцип - у нас есть класс, который принимает запросы от не авторизованного пользователя. Затем, когда пользователь авторизовался, выставляем другой обработчик пакетов(допустим, класс AuthPlayer, который реализует интерфейс IOperationHandler).

Это конечно не избавляет от switch в OnOperationRequest, но позволяет разбить логику на части и контролировать доступ.

ЗЫ Пример вроде с комнатами.
Аватара пользователя
afrokick
UNIт
 
Сообщения: 83
Зарегистрирован: 05 дек 2010, 23:36
Skype: alexandersosnovskiy
  • Сайт


Вернуться в Photon

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3