146 lines
4.4 KiB
C++
146 lines
4.4 KiB
C++
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
|
|
|
|
#include "SocketClientUDPSendDataThead.h"
|
|
|
|
FSocketClientUDPSendDataThead::FSocketClientUDPSendDataThead(USocketClientUDP* udpClientP, USocketClientBPLibrary* socketClientP, FString mySocketipP, int32 mySocketportP) :
|
|
udpClient(udpClientP),
|
|
socketClient(socketClientP),
|
|
mySocketip(mySocketipP),
|
|
mySocketport(mySocketportP) {
|
|
FString threadName = "FServerUDPSendMessageThread_" + FGuid::NewGuid().ToString();
|
|
thread = FRunnableThread::Create(this, *threadName, 0, EThreadPriority::TPri_Normal);
|
|
}
|
|
|
|
FSocketClientUDPSendDataThead::~FSocketClientUDPSendDataThead() {
|
|
delete thread;
|
|
}
|
|
|
|
uint32 FSocketClientUDPSendDataThead::Run() {
|
|
|
|
FSocket* socket = udpClient->getSocket();
|
|
FString connectionID = udpClient->getConnectionID();
|
|
maxPacketSize = udpClient->getMaxPacketSize();
|
|
|
|
while (udpClient->isRun() && socket != nullptr) {
|
|
|
|
|
|
if (udpClient->isRun() && (messageQueue.IsEmpty() == false || byteArrayQueue.IsEmpty() == false)) {
|
|
|
|
int32 sent = 0;
|
|
TArray<uint8> byteArray;
|
|
if (validInternetAdress) {
|
|
while (messageQueue.IsEmpty() == false) {
|
|
FString m;
|
|
messageQueue.Dequeue(m);
|
|
FTCHARToUTF8 Convert(*m);
|
|
byteArray.Append((uint8*)Convert.Get(), Convert.Length());
|
|
sendBytes(socket, byteArray, sent, internetAdress);
|
|
}
|
|
|
|
while (byteArrayQueue.IsEmpty() == false) {
|
|
byteArrayQueue.Dequeue(byteArray);
|
|
sendBytes(socket, byteArray, sent, internetAdress);
|
|
}
|
|
|
|
}
|
|
else {
|
|
UE_LOG(LogTemp, Error, TEXT("Can't send to %s:%i . Adress not valid."), *sendToip, sendToport);
|
|
}
|
|
|
|
}
|
|
|
|
if (udpClient->isRun()) {
|
|
pauseThread(true);
|
|
//workaround. suspend do not work on all platforms. lets sleep
|
|
while (paused && udpClient->isRun()) {
|
|
FPlatformProcess::Sleep(0.01);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (socket != nullptr) {
|
|
socket->Close();
|
|
socket = nullptr;
|
|
udpClient->setSocket(nullptr);
|
|
}
|
|
|
|
|
|
USocketClientBPLibrary* socketClientTMP = socketClient;
|
|
USocketClientUDP* udpClientGlobal = udpClient;
|
|
FString ipGlobal = mySocketip;
|
|
int32 portGlobal = mySocketport;
|
|
AsyncTask(ENamedThreads::GameThread, [socketClientTMP, udpClientGlobal, ipGlobal, portGlobal, connectionID]() {
|
|
if (socketClientTMP != nullptr)
|
|
socketClientTMP->onsocketClientUDPConnectionEventDelegate.Broadcast(false, "UDP connection closed. " + ipGlobal + ":" + FString::FromInt(portGlobal), connectionID);
|
|
if (udpClientGlobal != nullptr)
|
|
udpClientGlobal->onsocketClientUDPConnectionEventDelegate.Broadcast(false, "UDP connection closed. " + ipGlobal + ":" + FString::FromInt(portGlobal), connectionID);
|
|
});
|
|
|
|
|
|
thread = nullptr;
|
|
return 0;
|
|
}
|
|
|
|
|
|
void FSocketClientUDPSendDataThead::addData(FString messageP, TArray<uint8> byteArrayP, FString domainOrIP, int32 port, ESocketClientIPType ipType) {
|
|
|
|
//new adress?
|
|
if (sendToport != port || sendToDomainOrIP.Equals(domainOrIP) == false) {
|
|
|
|
sendToDomainOrIP = domainOrIP;
|
|
sendToip = socketClient->resolveDomain(domainOrIP, ipType);
|
|
sendToport = port;
|
|
|
|
internetAdress->SetIp(*sendToip, validInternetAdress);
|
|
internetAdress->SetPort(sendToport);
|
|
if (!validInternetAdress) {
|
|
//don't send to many error messages. one second = 10000000 ticks
|
|
if (((FDateTime::Now().GetTicks()) - lastErrorMessageTime) >= 10000000) {
|
|
UE_LOG(LogTemp, Error, TEXT("Can't create Adress %s:%i"), *sendToip, sendToport);
|
|
lastErrorMessageTime = FDateTime::Now().GetTicks();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (!validInternetAdress) {
|
|
return;
|
|
}
|
|
|
|
if (messageP.Len() > 0)
|
|
messageQueue.Enqueue(messageP);
|
|
if (byteArrayP.Num() > 0)
|
|
byteArrayQueue.Enqueue(byteArrayP);
|
|
pauseThread(false);
|
|
|
|
}
|
|
|
|
void FSocketClientUDPSendDataThead::pauseThread(bool pause) {
|
|
paused = pause;
|
|
if (thread != nullptr)
|
|
thread->Suspend(pause);
|
|
}
|
|
|
|
void FSocketClientUDPSendDataThead::sendBytes(FSocket*& socketP, TArray<uint8>& byteArray, int32& sent, TSharedRef<FInternetAddr>& addr) {
|
|
if (byteArray.Num() > maxPacketSize) {
|
|
TArray<uint8> byteArrayTemp;
|
|
for (int32 i = 0; i < byteArray.Num(); i++) {
|
|
byteArrayTemp.Add(byteArray[i]);
|
|
if (byteArrayTemp.Num() == maxPacketSize) {
|
|
sent = 0;
|
|
socketP->SendTo(byteArrayTemp.GetData(), byteArrayTemp.Num(), sent, *addr);
|
|
byteArrayTemp.Empty();
|
|
}
|
|
}
|
|
if (byteArrayTemp.Num() > 0) {
|
|
sent = 0;
|
|
socketP->SendTo(byteArrayTemp.GetData(), byteArrayTemp.Num(), sent, *addr);
|
|
byteArrayTemp.Empty();
|
|
}
|
|
}
|
|
else {
|
|
sent = 0;
|
|
socketP->SendTo(byteArray.GetData(), byteArray.Num(), sent, *addr);
|
|
}
|
|
|
|
byteArray.Empty();
|
|
} |