Thread and websockets

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?