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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

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


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

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

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

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

                                                                                                                                                         
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(); // Отправляем запрос.
  }
  ...
};

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

// Три параметра соответственно:
//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/


Интересные статьи

Интересные статьи

В настоящей статье расскажу историю о том, как можно столкнуться с довольно простой проблемой на больших инсталляциях продуктов компании Atlassian, в частности на Jira.&n...
Хочу поделиться опытом автоматизации экспорта заказов из Aliexpress в несколько CRM. Приведенные примеры написаны на PHP, но библиотеки для работы с Aliexpress есть и для...
В этой статье описываются некоторые методы ускорения загрузки фронтенд-приложений, чтобы реализовать отзывчивый, быстрый пользовательский интерфейс. Мы обсудим общую архитектуру фронтенда, как...
Это продолжение статьи «Проблемы пакетной обработки запросов и их решения». Рекомендуется сначала ознакомиться с первой частью, так как в ней подробно описана суть задачи и некоторые подходы к ...
Я довольно давно работаю DBA + database performance expert + еще много чего в одной крупной компании. Работа очень комфортная, но какое-то время я переживал из-за того, что моя позиция тупиковая....