Didn't Get any Response from Http Request

Hi,

I was trying to write a login system in my game connected to my own server. After searching online, I used the MySQL database and python flask on my server to receive and give the information.

The question is: The server got the request which had the information I entered in the game and should return a JSON message, but the game did not receive it. The response function I bound to the request is never executed in c++.

Here is the part of the code I wrote.

In HTTPService.cpp:

FHttpRequestRef UHTTPService::RequestWithRoute(FString Subroute)
{
	FHttpRequestRef Request = FHttpModule::Get().CreateRequest();
	FString TargetURL = TEXT("My IP Address") + Subroute;
	Request->SetURL(TargetURL);
	UE_LOG(LogTemp, Warning, TEXT("Request URL is: %s"), *Request->GetURL());
	SetRequestHeader(Request);
	return Request;
}

void UHTTPService::SetRequestHeader(FHttpRequestRef& Request)
{
	Request->SetHeader(TEXT("User-Agent"), TEXT("X-UnrealEngine-Agent"));
	Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
	Request->SetHeader(TEXT("Accepts"), TEXT("application/json"));
}

FHttpRequestRef UHTTPService::GetRequest(FString Subroute)
{
	FHttpRequestRef Request = RequestWithRoute(Subroute);
	Request->SetVerb("GET");
	return Request;
}

FHttpRequestRef UHTTPService::PostRequest(FString Subroute, FString JsonString)
{
	FHttpRequestRef Request = RequestWithRoute(Subroute);
	Request->SetVerb("POST");
	Request->SetContentAsString(JsonString);
	return Request;
}

void UHTTPService::Send(FHttpRequestRef& Request)
{
	Request->ProcessRequest();
}

//This part is executed.
void UHTTPService::StartLogin(FLogin_Request LoginCredentials)
{
	FString JsonString;
	GetJsonStringFromStruct<FLogin_Request>(LoginCredentials, JsonString);
	UE_LOG(LogTemp, Warning, TEXT("JsonString is: %s"), *JsonString);

	TSharedRef<IHttpRequest> Request = PostRequest("login", JsonString);
	Request->OnProcessRequestComplete().BindUObject(this, &UHTTPService::LoginResponse);
	Send(Request); 
}

// This method is never executed
void UHTTPService::LoginResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
	if (!ResponseIsValid(Response, bWasSuccessful)) return; 

	FLogin_Response LoginResponse;
	GetStructFromJsonString<FLogin_Response>(Response, LoginResponse);

	UE_LOG(LogTemp, Warning, TEXT("Id is: %d"), LoginResponse.Id);
	UE_LOG(LogTemp, Warning, TEXT("Name is: %s"), *LoginResponse.UserName);
}

bool UHTTPService::ResponseIsValid(FHttpResponsePtr Response, bool bWasSuccessful)
{
	if (!bWasSuccessful || !Response.IsValid()) return false;
	if (EHttpResponseCodes::IsOk(Response->GetResponseCode())) return true;
	else {
		UE_LOG(LogTemp, Warning, TEXT("Http response return error code: %d"), Response->GetResponseCode());
		return false;
	}
}

On the server, I wrote these:

login.py:

@app.route('/login', methods=['GET', 'POST'])
def login():
	content = request.get_json(force=True)

	if request.method == 'POST':
		print ('Incoming request...')
		username = content['username']
		password = content['password']

		print ('The username:', username, ' and password: ', password)
		cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
		cursor.execute('SELECT * FROM accounts WHERE username = %s AND password = %s', (username, password))
		account = cursor.fetchone()

		if account:
			print ('Found user in database...')
			session['loggedin'] = True
			session['username'] = account['username']
			session['id'] = account['id']
			print ('Returning the message...')
			return jsonify({'id':account['id'], 'username':account['username'], 'message':'Logged in successfully.'})
		else:
			print ('Did not find the user in database...')
			print ('Sending back error message...')
			message = {'message':'Incorrect username or password.'}
	print ('Sending back error message...')
	return jsonify(message)

The result in the server when running “login.py” is this:
server

The output log in the game is:
client
It stops here, and not executed the “LoginResponse” method.

Hope this information can help you understand what I did and please give me some advice on how to fix the problem. Thanks.

Hey, not sure if you did it for your own Security, or I don’t have function on my end here, but I don’t see implementation of PostRequest method.

Here is the code I used for my game, and it works fine. So check it out, and see if you missed something

	// Create HTTP Request
	TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest();
	HttpRequest->SetVerb("GET");
	HttpRequest->SetHeader("Content-Type", "application/json");
	HttpRequest->SetURL("https://myWebSite/MyFile.php");

	// Setup Async response
	HttpRequest->OnProcessRequestComplete().BindUObject(this, &MyClass::ServerListPopulateComplete);
	HttpRequest->ProcessRequest();

Also, check these out, maybe you will find some solution

Try to google out unreal engine OnProcessRequestComplete not executed, I found couple of threads.

1 Like

Hi, thanks for your reply, I forgot to add the post method and now I edit my question. Please take a look. And I will check the post you linked here and google the threads to see if those can fix my problem. Thanks again.

OK, I see it now. Chek out my code also. Even though it’s “GET”.
As I said, it works for me.

Also check out this video: Unreal Engine C++ Persistence #5: "Send POST Request" - YouTube

Aaand, I googled this example out :slight_smile:

Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
Request->SetURL("http://localhost/api.php");
Request->SetVerb("POST");

Request->SetContentAsString(JsonString);
Request->OnProcessRequestComplete().BindUObject(this, &UAuthWidget::OnResponseReceived);
Request->ProcessRequest();
Request->SetHeader(TEXT("User-Agent"), TEXT("X-UnrealEngine-Agent"));
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
Request->SetHeader(TEXT("Accepts"), TEXT("application/json"));
Request->SetHeader(TEXT("Accept-Encoding"), TEXT("identity"));

Thank you very much! I will try these out.

2 Likes

I think I know what is the problem. There is something wrong with the UObject class. I write my UHTTPService.h under UObject class.

After I test your code in the Actor class inherited from AActor and paste mine code into the same Actor class. it works. Everything is fine.
So I guess that the Request->OnProcessRequestComplete().BindUObject() function does not work in the UObject class somehow.

The reason why I used the UObject is that I want to make it portable so that when I need this feature, I can just copy and paste the files into the new projects and include them in other c++ files. I guess I can take it with AActor for now. If this is not the proper way to do such a thing, do you know which class or which way I should do it to make it portable?

Anyway, thanks, after three hours, finally knows where is the problem. Soooooo tired.

1 Like