No worries glad this helped some people. I honestly spent forever looking as well. As far as the UDPReceiveWorker.h goes, that was something I was working on as to get the handling of receiving messages in another thread so the game does wait for a response. I never could get it to work properly.
UDPReceiveWorker.h
#include "Networking.h"
#include "UDPNetworkingWrapper.h"
#include "NetworkingFunctionLibrary.h"
#include <string>
/**
* This class holds the multi threading data for receiving UDP packets
*/
class VIRTUALTABLETOP_API UDPReceiveWorker : public FRunnable
{
// Singleton instance, can access the thread at anytime.
static UDPReceiveWorker* Runnable;
// The data
TArray<uint8>* ReceivedDataRef;
/** Stop this thread? Uses Thread Safe Counter */
FThreadSafeCounter StopTaskCounter;
public:
UDPReceiveWorker(TArray<uint8>& ReceivedData, FSocket* InSocket, FTimespan& InWaitTime);
virtual ~UDPReceiveWorker();
// Begin FRunnable interface.
virtual bool Init();
virtual uint32 Run();
virtual void Stop();
// End FRunnable interface
void EnsureCompletion();
static UDPReceiveWorker* JoyInit(TArray<uint8>& ReceivedData, FSocket* InSocket, FTimespan& InWaitTime);
/** Shuts down the thread. Static so it can easily be called from outside the thread context */
static void Shutdown();
private:
// Holds the network socket.
FSocket* Socket;
// Holds a pointer to the socket sub-system.
ISocketSubsystem* SocketSubsystem;
// Holds a flag indicating that the thread is stopping.
bool Stopping;
// Holds the thread object.
FRunnableThread* Thread;
// Holds the amount of time to wait for inbound packets.
FTimespan WaitTime;
};
UDPReceiverWorker.cpp
include "VirtualTabletop.h"
#include "UDPReceiveWorker.h"
UDPReceiveWorker* UDPReceiveWorker::Runnable = NULL;
UDPReceiveWorker::UDPReceiveWorker(TArray<uint8>& ReceivedData, FSocket* InSocket, FTimespan& InWaitTime)
: Socket(InSocket)
, StopTaskCounter(0)
, WaitTime(InWaitTime)
, Stopping(false)
{
const bool bAutoDeleteSelf = false;
const bool bAutoDeleteRunnable = false;
// Link the data
ReceivedDataRef = &ReceivedData;
SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
Thread = FRunnableThread::Create(this, TEXT("UDPReceiveWorker"), 0, TPri_BelowNormal); //windows default = 8mb for thread, could specify more
}
UDPReceiveWorker::~UDPReceiveWorker()
{
delete Thread;
Thread = NULL;
SocketSubsystem = nullptr;
Socket = nullptr;
ReceivedDataRef = nullptr;
//myNetworkingWrapper = nullptr;
}
// Init
bool UDPReceiveWorker::Init()
{
return true;
}
//Run
uint32 UDPReceiveWorker::Run()
{
TSharedRef<FInternetAddr> Sender = SocketSubsystem->CreateInternetAddr();
while (!Stopping)
{
if (!Socket->Wait(ESocketWaitConditions::WaitForRead, WaitTime))
{
continue;
}
uint32 Size;
while (Socket->HasPendingData(Size))
{
int32 Read = 0;
Socket->RecvFrom(ReceivedDataRef->GetData(), ReceivedDataRef->Num(), Read, *Sender);
}
}
return 0;
}
// Stop
void UDPReceiveWorker::Stop()
{
StopTaskCounter.Increment();
}
UDPReceiveWorker* UDPReceiveWorker::JoyInit(TArray<uint8>& ReceivedData, FSocket* InSocket, FTimespan& InWaitTime)
{
//Create new instance of thread if it does not exist
// and the platform supports multi threading!
if (!Runnable && FPlatformProcess::SupportsMultithreading())
{
Runnable = new UDPReceiveWorker(ReceivedData, InSocket, InWaitTime);
}
return Runnable;
}
void UDPReceiveWorker::EnsureCompletion()
{
Stop();
Thread->WaitForCompletion();
}
void UDPReceiveWorker::Shutdown()
{
if (Runnable)
{
Runnable->EnsureCompletion();
delete Runnable;
Runnable = NULL;
}
}
//
//bool UDPReceiveWorker::IsThreadFinished()
//{
// if (Runnable) return Runnable->IsFinished();
// return true;
//}
If you get this working please share with us.