Using Timers inside of Lambda functions

I am using a WebSocket and applying a Lambda to the OnMessage callback.

Socket->OnMessage().AddLambda([&](const FString& Message)
	{
		if (IsValid(this))
                {
		        this->StartHeartbeat();
                }
	});

And in StartHeartbeat function I create a timer like this:

void UStartGateway::StartHeartbeat()
{
	HeartbeatCallback.BindWeakLambda(this, [this]
	{
		Heartbeat();
	});
	GetWorld()->GetTimerManager().SetTimer(HeartbeatHandle, HeartbeatCallback, HeartbeatInterval / 1000, true);
}

And when I receive a message on the websocket I get an access violation error and the editor crashes. The error specifically points to the timer setting line. Any help is greatly appreciated. I really don’t understand the issue, since ‘this’ is being captured in both lambdas and I’m pretty sure that the object isn’t being destroyed somehow, but I have IsValid(this) protecting the StartHeartbeat from running anyway.

It’s hard to say, you would be best off debugging the issue and looking deeper into what’s causing the error. The only thing I can think of is that the object might not have a valid world reference. Is your UStartGateway an actor/scene component or do you have the function overridden to provide it? It might be the case that GetWorld() returns nullptr and then you try to get the timer manager from it, resulting in the access violation.

That makes a lot of sense. UStartGateway inherits from BlueprintAsyncActionBase so it’s just a blueprint node and thus GetWorld() was returning a nullptr.

I have updated my code to get a WorldContext object in the constructor of my node using the meta tag and using that to get the game instance and start a timer on the game instance. Since, for my node, it would need to keep the timer valid across worlds.

Thanks for the help.