diff --git a/Source/SocketIOClient/Private/SocketIONative.cpp b/Source/SocketIOClient/Private/SocketIONative.cpp index 3dcffb5..9235b29 100644 --- a/Source/SocketIOClient/Private/SocketIONative.cpp +++ b/Source/SocketIOClient/Private/SocketIONative.cpp @@ -501,11 +501,18 @@ void FSocketIONative::SetupInternalCallbacks() { if (bCallbackOnGameThread) { - FCULambdaRunnable::RunShortLambdaOnGameThread([&, DisconnectReason] + // Capture a weak ref to self instead of `this`: this lambda runs later on the + // game thread, by which point the FSocketIONative may have been released (e.g. + // during a level transition). Pin() safely no-ops if it's gone. + TWeakPtr WeakSelf = AsShared(); + FCULambdaRunnable::RunShortLambdaOnGameThread([WeakSelf, DisconnectReason] { - if (OnDisconnectedCallback) + if (TSharedPtr Self = WeakSelf.Pin()) { - OnDisconnectedCallback(DisconnectReason); + if (Self->OnDisconnectedCallback) + { + Self->OnDisconnectedCallback(DisconnectReason); + } } }); } @@ -537,11 +544,15 @@ void FSocketIONative::SetupInternalCallbacks() { if (bCallbackOnGameThread) { - FCULambdaRunnable::RunShortLambdaOnGameThread([&] + TWeakPtr WeakSelf = AsShared(); + FCULambdaRunnable::RunShortLambdaOnGameThread([WeakSelf] { - if (OnConnectedCallback) + if (TSharedPtr Self = WeakSelf.Pin()) { - OnConnectedCallback(SocketId, SessionId); + if (Self->OnConnectedCallback) + { + Self->OnConnectedCallback(Self->SocketId, Self->SessionId); + } } }); } @@ -562,11 +573,15 @@ void FSocketIONative::SetupInternalCallbacks() { if (bCallbackOnGameThread) { - FCULambdaRunnable::RunShortLambdaOnGameThread([&, Namespace] + TWeakPtr WeakSelf = AsShared(); + FCULambdaRunnable::RunShortLambdaOnGameThread([WeakSelf, Namespace] { - if (OnNamespaceConnectedCallback) + if (TSharedPtr Self = WeakSelf.Pin()) { - OnNamespaceConnectedCallback(Namespace); + if (Self->OnNamespaceConnectedCallback) + { + Self->OnNamespaceConnectedCallback(Namespace); + } } }); } @@ -593,11 +608,15 @@ void FSocketIONative::SetupInternalCallbacks() { if (bCallbackOnGameThread) { - FCULambdaRunnable::RunShortLambdaOnGameThread([&, Namespace] + TWeakPtr WeakSelf = AsShared(); + FCULambdaRunnable::RunShortLambdaOnGameThread([WeakSelf, Namespace] { - if (OnNamespaceDisconnectedCallback) + if (TSharedPtr Self = WeakSelf.Pin()) { - OnNamespaceDisconnectedCallback(Namespace); + if (Self->OnNamespaceDisconnectedCallback) + { + Self->OnNamespaceDisconnectedCallback(Namespace); + } } }); } @@ -618,11 +637,15 @@ void FSocketIONative::SetupInternalCallbacks() { if (bCallbackOnGameThread) { - FCULambdaRunnable::RunShortLambdaOnGameThread([&] + TWeakPtr WeakSelf = AsShared(); + FCULambdaRunnable::RunShortLambdaOnGameThread([WeakSelf] { - if (OnFailCallback) + if (TSharedPtr Self = WeakSelf.Pin()) { - OnFailCallback(); + if (Self->OnFailCallback) + { + Self->OnFailCallback(); + } } }); } @@ -645,11 +668,15 @@ void FSocketIONative::SetupInternalCallbacks() { if (bCallbackOnGameThread) { - FCULambdaRunnable::RunShortLambdaOnGameThread([&, num, delay] + TWeakPtr WeakSelf = AsShared(); + FCULambdaRunnable::RunShortLambdaOnGameThread([WeakSelf, num, delay] { - if (OnReconnectionCallback) + if (TSharedPtr Self = WeakSelf.Pin()) { - OnReconnectionCallback(num, delay); + if (Self->OnReconnectionCallback) + { + Self->OnReconnectionCallback(num, delay); + } } }); } diff --git a/Source/SocketIOClient/Public/SocketIONative.h b/Source/SocketIOClient/Public/SocketIONative.h index d198fd1..a1bd9ab 100644 --- a/Source/SocketIOClient/Public/SocketIONative.h +++ b/Source/SocketIOClient/Public/SocketIONative.h @@ -39,7 +39,7 @@ struct FSIOBoundEvent } }; -class SOCKETIOCLIENT_API FSocketIONative +class SOCKETIOCLIENT_API FSocketIONative : public TSharedFromThis { public: /** By default TLS verification is off. TLS mode will be set by URL on connect.*/