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

Kate

Administrator
Команда форума
В этой статье я разберу небольшую, но очень полезную тему 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;
}
};

 
Сверху