Hello!
I hope I’m posting in the right place, I decided to post it here since I will be quoting the engine code itself. I want to share some of the problems I found while trying to use the HTTP Server Module (HttpServer | Unreal Engine Documentation).
[Just in case you are wondering I’m using it for client side google authentication, so I execute the flow in a browser and then redirect to a local http server in my game and get the user’s access token]
First problem: I cannot stop the listeners. The problem is although the StopAllListeners()
method stops the listeners, it doesn’t actually remove them from the listeners list, so next time the listener ticks an assertions will fail.
void FHttpServerModule::StopAllListeners()
{
UE_LOG(LogHttpServerModule, Log,
TEXT("Stopping all listeners..."));
for (const auto& Listener : Listeners)
{
if (Listener.Value->IsListening())
{
Listener.Value->StopListening();
}
}
UE_LOG(LogHttpServerModule, Log,
TEXT("All listeners stopped"));
}
void FHttpListener::Tick(float DeltaTime)
{
// Accept new connections
AcceptConnections(MaxConnectionsToAcceptPerFrame);
// Tick Connections
TickConnections(DeltaTime);
// Remove any destroyed connections
RemoveDestroyedConnections();
}
void FHttpListener::AcceptConnections(uint32 MaxConnectionsToAccept)
{
check(ListenSocket); // <--- this assertion fails
....
}
Second problem: the previous problem causes the http server to always keep the port bind until the end of the process, preventing another client to start its own server. I decided to workaround this problem by retrying with another port if the server cannot be bind. The problem is the module is swallowing those errors.
As you can see the http listener will return true if the socket can be bind:
bool FHttpListener::StartListening()
{
...
// Bind to Localhost/Caller-defined port
TSharedRef<FInternetAddr> LocalhostAddr = SocketSubsystem->CreateInternetAddr();
LocalhostAddr->SetAnyAddress();
LocalhostAddr->SetPort(ListenPort);
if (!ListenSocket->Bind(*LocalhostAddr))
{
UE_LOG(LogHttpListener, Error,
TEXT("HttpListener unable to bind to %s"),
*LocalhostAddr->ToString(true));
return false;
}
...
UE_LOG(LogHttpListener, Log,
TEXT("Created new HttpListener on port %u"), ListenPort);
return true;
}
but the module swallows the error:
void FHttpServerModule::StartAllListeners()
{
bHttpListenersEnabled = true;
UE_LOG(LogHttpServerModule, Log,
TEXT("Starting all listeners..."));
for (const auto& Listener : Listeners)
{
if (!Listener.Value->IsListening())
{
Listener.Value->StartListening();
}
}
UE_LOG(LogHttpServerModule, Log,
TEXT("All listeners started"));
}
Not sure if I’m missing something (and pretty new to unreal) or if there are bugs (which is what I suspect), and I’m also not sure if this is the right place to post a bug, but decided to start somewhere!.
Thanks!