Hi, I have an issue with thread and synchronization using events. Here my goal is to wait until a websocket is connected.
To do so, I want my init function to wait until an event is sent on OnConnected().
For that I use FEvent thanks to this tutorial on the unreal community wiki.
However, the Wait function always goes to the timeout and the event is raised just after… I seems that the callback raising the event cannot be called while the function is waiting.
I code this :
MyActor.h
#pragma once
#include "IWebSocket.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()
class MINIMALWEBSOCKET_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
void initialize();
TSharedPtr<IWebSocket> socket_ = nullptr;
FEvent* U_Semaphore;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
MyActor.cpp
#include "MyActor.h"
#include <time.h>
#include "WebSocketsModule.h"
// Sets default values
AMyActor::AMyActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
void AMyActor::initialize()
{
U_Semaphore = FGenericPlatformProcess::GetSynchEventFromPool(false);
FString IPAddress = "127.0.0.1";
int Port = 9090;
FString ConnectMsg = FString::Printf(TEXT("ws://%s:%d/"), *IPAddress, Port);
UE_LOG(LogTemp, Warning, TEXT("Init --- : %s Test"), *ConnectMsg);
socket_ = FWebSocketsModule::Get().CreateWebSocket(FString::Printf(TEXT("ws://%s:%d/"),*IPAddress, Port), TEXT("ws"));
socket_->OnConnected().AddLambda([this]()->void {
if (U_Semaphore)
U_Semaphore->Trigger();
else
UE_LOG(LogTemp, Warning, TEXT("Semaphore not exist"));
UE_LOG(LogTemp, Warning, TEXT("Connect ok %d"), time(NULL));
});
socket_->Connect();
if(!U_Semaphore->Wait(10000))
UE_LOG(LogTemp, Error, TEXT("Timeout %d"), time(NULL));
UE_LOG(LogTemp, Warning, TEXT("Pass Connect %d"), time(NULL));
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
initialize();
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
The log is the following:
LogTemp: Warning: Init --- : ws://127.0.0.1:9090/ Test
LogTemp: Error: Timeout 1654003202
LogTemp: Warning: Pass Connect 1654003202
PIE: Server logged in
PIE: Play in editor total start time 10.042 seconds.
LogTemp: Warning: Connect ok 1654003202
Does anyone know what I do wrong or if it’s not feasible?