HTTP менеджер запросов в Unreal Engine

от автора

Приветствую, Хабр!

В этой статье я разберу небольшую, но очень полезную тему HTTP запросов в UE. Все будет выполнено строго на C++.


Основная часть

Для отправки запроса нам потребуется Singleton объект выглядящий следующим образом:

FHttpModule* Module = &FHttpModule::Get();

Его мы и будем использовать для запросов. Далее необходимо заполнить запрос параметрами и отправить. Тестовый класс назовем Data и поместим туда пару полей. Сам запрос представляет из себя голый объект, который необходимо обернуть в TSharedRef<>.

                                                                                                                                                          USTRUCT() struct FData  { GENERATED_BODY()      UPROPERTY()   int32 ID{-1);   UPROPERTY()   FString Name{};             }; class ThisClass {   //Создание запроса.   void MakeRequest()   {     FHttpModule* Module = &FHttpModule::Get();     TSharedRef<IHttpRequest,ESPMode::ThreadSafe> Request = Module->CreateRequest();     Request->OnProcessRequestComplete().BindRaw(this,&ThisClass::OnPostReceivedResponse);// Подвязываемся на делегат получения запроса.     Request->SetURL(GetFullPathURL()); //Выставляем URL. В моем случае - абстрактный путь куда-нибудь     Request->SetVerb("POST"); //Непосредственно сам глагол.     Request->SetHeader(GetDefaultHeader().Key,GetDefaultHeader().Value);//Опять же, абстрактный хеддер. В вашем случае все зависит от API.     Request->SetContentAsString(GetContent());//Абстрактная строка, некогда бывшая Json файлом. (Об этом Ниже).     Request->ProcessRequest(); // Отправляем запрос.   }   ... }; 

После получения запроса будет вызвана следующая функция:

// Три параметра соответственно: //Request - сам запрос. //Response - ответ. //bWasSuccessful - флаг ошибки. void ThisClass::OnPostReceivedResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) {   //Если запрос успешен и ответ валиден. if(bWasSuccessful && Response.Get())   {     Response->GetContentAsString(); //Делаем чтонибудь с ответом.   } }

Теперь встал вопрос обработки сей строки. Должен признать, когда я только столкнулся с задачей обработать запрос, то сделал максимально просто: написал парсер, который заполняет json и вытаскивает данные из него. Проблема была в том, что для каждого отдельного json’а приходилось писать парсер, что убивало много времени. В конце концов я нашел нативный инструмент, который каждую структуру, помеченную как USTRUCT(), парсит автоматически.

USTRUCT() struct FData  { GENERATED_BODY()      int32 ID{-1);   FString Name{}; };  class ThisClass { void MakeRequest()   {   FHttpModule* Module = &FHttpModule::Get(); TSharedRef<IHttpRequest,ESPMode::ThreadSafe> Request = Module->CreateRequest(); Request->OnProcessRequestComplete().BindRaw(this,&ThisClass::OnPostReceivedResponse);// Подвязываемся на делегат получения запроса. Request->SetURL(GetFullPathURL()); //Выставляем URL. В моем случае - абстрактный путь куда-нибудь Request->SetVerb("POST"); //Непосредственно сам глагол. Request->SetHeader(GetDefaultHeader().Key,GetDefaultHeader().Value);//Опять же, абстрактный хеддер. В вашем случае все зависит от API.     Request->SetContentAsString(GetContent());//Абстрактная строка, некогда бывшая Json файлом. Request->ProcessRequest(); // Отправляем запрос.   }   void OnPostReceivedResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)   {     //Если запрос успешен и ответ валиден.     if(bWasSuccessful && Response.Get())   {    FData Data;       //Объект сразу закастится к типу FData и будет помещен в out параметр Data.        FJsonObjectConverter::JsonObjectStringToUStruct<FData>(Response->GetContentAsString(),&Data);       Data.ID;//Теперь можно использовать эти данные.       Data.Name;     }   }   //Таким же образом будет выглядеть преобразование из структуры в строку:   FString GetContent(const FData& Object)   {     FString ReturnStrung; FJsonObjectConverter::UStructToJsonObjectString<FData>(Object,&ReturnStrung);     return ReturnString;   } };

Послесловие

Тему отправки и принятия запросов можно продолжить и далее, если задаться вопросами: А как мы поймем что получили все отправленные запросы? И как быть в ситуации, когда нам необходимо сохранять множественные данные, вложенные друг в друга? А что если мы захотим отправить 100 запросов, и каждый ответ нужно обработать отдельно? Не хотелось лишний раз перегружать эту статью, посему если вы поддержите, напишу продолжение.

Задавайте вопросы и кидайте предложения для следующих статей.

Буду рад любой адекватной критике.

Спасибо, что читали!


ссылка на оригинал статьи https://habr.com/ru/post/599295/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *