167 lines
5.1 KiB
C++
167 lines
5.1 KiB
C++
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
|
|
|
|
#include "SocketClientTCPSendDataThead.h"
|
|
|
|
|
|
FSocketClientTCPSendDataThead::FSocketClientTCPSendDataThead(USocketClientBPLibrary* socketClientLibP, USocketClientTCPClient* tcpClientP, FString clientConnectionIDP) :
|
|
socketClientLib(socketClientLibP),
|
|
tcpClient(tcpClientP),
|
|
clientConnectionID(clientConnectionIDP) {
|
|
FString threadName = "FSendDataToServerThread" + FGuid::NewGuid().ToString();
|
|
thread = FRunnableThread::Create(this, *threadName, 0, EThreadPriority::TPri_Normal);
|
|
}
|
|
|
|
FSocketClientTCPSendDataThead::~FSocketClientTCPSendDataThead() {
|
|
delete thread;
|
|
}
|
|
|
|
uint32 FSocketClientTCPSendDataThead::Run(){
|
|
|
|
if (tcpClient == nullptr) {
|
|
UE_LOG(LogTemp, Error, TEXT("Class is not initialized."));
|
|
return 0;
|
|
}
|
|
|
|
/*if (GEngine)
|
|
GEngine->AddOnScreenDebugMessage(-1, 20.0f, FColor::Green, TEXT("tcp socket 1"));*/
|
|
|
|
FString clientConnectionIDGlobal = clientConnectionID;
|
|
USocketClientBPLibrary* socketClientLibGlobal = socketClientLib;
|
|
|
|
//message wrapping
|
|
FString stringSeparator = FString();
|
|
uint8 byteSeparator = 0x00;
|
|
ESocketClientTCPSeparator messageWrapping = ESocketClientTCPSeparator::E_None;
|
|
tcpClient->getTcpSeparator(stringSeparator, byteSeparator, messageWrapping);
|
|
|
|
TArray<TCHAR> stringSeparatorArray = stringSeparator.GetCharArray();
|
|
if (stringSeparatorArray.Num() > 0 && stringSeparatorArray.Last() == 0x00) {
|
|
stringSeparatorArray.RemoveAt(stringSeparatorArray.Num() - 1, 1, true);
|
|
}
|
|
|
|
if (messageWrapping == ESocketClientTCPSeparator::E_LengthSeparator && stringSeparatorArray.Num() == 0) {
|
|
messageWrapping = ESocketClientTCPSeparator::E_None;
|
|
UE_LOG(LogTemp, Warning, TEXT("Socket Client Plugin: Separator mode is set to String but there is no String Separator. Mode changed to none."));
|
|
}
|
|
|
|
// get the socket
|
|
FSocket* socket = tcpClient->getSocket();
|
|
int32 sent = 0;
|
|
|
|
while (tcpClient->isRun()) {
|
|
|
|
// try to connect to the server
|
|
if (socket == NULL || socket == nullptr) {
|
|
UE_LOG(LogTemp, Error, TEXT("Connection not exist."));
|
|
//AsyncTask(ENamedThreads::GameThread, [clientConnectionIDGlobal, socketClientLibGlobal]() {
|
|
// if (socketClientLibGlobal != nullptr) {
|
|
// socketClientLibGlobal->onsocketClientTCPConnectionEventDelegate.Broadcast(false, "Connection not exist:" + clientConnectionIDGlobal, clientConnectionIDGlobal);
|
|
// socketClientLibGlobal->closeSocketClientConnection();
|
|
// }
|
|
//});
|
|
break;
|
|
}
|
|
|
|
if (socket != nullptr && tcpClient->isRun()) {
|
|
|
|
while (messageQueue.IsEmpty() == false) {
|
|
FString m;
|
|
messageQueue.Dequeue(m);
|
|
FTCHARToUTF8 Convert(*m);
|
|
sent = 0;
|
|
|
|
TArray<uint8> byteCache;
|
|
|
|
switch (messageWrapping)
|
|
{
|
|
case ESocketClientTCPSeparator::E_None:
|
|
byteCache.Append((uint8*)Convert.Get(), Convert.Length());
|
|
break;
|
|
case ESocketClientTCPSeparator::E_ByteSeparator:
|
|
byteCache.Append((uint8*)Convert.Get(), Convert.Length());
|
|
byteCache.Add(byteSeparator);
|
|
break;
|
|
case ESocketClientTCPSeparator::E_StringSeparator:
|
|
{
|
|
m += stringSeparator;
|
|
FTCHARToUTF8 ConvertWithSeparator(*m);
|
|
byteCache.Append((uint8*)ConvertWithSeparator.Get(), ConvertWithSeparator.Length());
|
|
}
|
|
break;
|
|
case ESocketClientTCPSeparator::E_LengthSeparator:
|
|
if (FGenericPlatformProperties::IsLittleEndian()) {
|
|
byteCache.Add(0x00);
|
|
}
|
|
else {
|
|
byteCache.Add(0x01);
|
|
}
|
|
byteCache.SetNum(5);
|
|
int32 dataLength = Convert.Length();
|
|
FMemory::Memcpy(byteCache.GetData() + 1, &dataLength, 4);
|
|
byteCache.Append((uint8*)Convert.Get(), Convert.Length());
|
|
break;
|
|
}
|
|
|
|
socket->Send(byteCache.GetData(), byteCache.Num(), sent);
|
|
}
|
|
|
|
while (byteArrayQueue.IsEmpty() == false) {
|
|
|
|
TArray<uint8> byteCache;
|
|
byteArrayQueue.Dequeue(byteCache);
|
|
sent = 0;
|
|
|
|
switch (messageWrapping)
|
|
{
|
|
case ESocketClientTCPSeparator::E_ByteSeparator:
|
|
byteCache.Add(byteSeparator);
|
|
break;
|
|
case ESocketClientTCPSeparator::E_StringSeparator:
|
|
{
|
|
FTCHARToUTF8 ConvertWithSeparator(*stringSeparator);
|
|
byteCache.Append((uint8*)ConvertWithSeparator.Get(), ConvertWithSeparator.Length());
|
|
}
|
|
break;
|
|
case ESocketClientTCPSeparator::E_LengthSeparator:
|
|
byteCache.InsertZeroed(0, 5);
|
|
if (FGenericPlatformProperties::IsLittleEndian() == false) {
|
|
uint8 a = 0x01;
|
|
FMemory::Memcpy(byteCache.GetData(), &a, 1);
|
|
}
|
|
int32 dataLength = byteCache.Num() - 5;
|
|
FMemory::Memcpy(byteCache.GetData() + 1, &dataLength, 4);
|
|
break;
|
|
}
|
|
|
|
socket->Send(byteCache.GetData(), byteCache.Num(), sent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tcpClient->isRun()) {
|
|
pauseThread(true);
|
|
//workaround. suspend do not work on all platforms. lets sleep
|
|
while (paused && tcpClient->isRun()) {
|
|
FPlatformProcess::Sleep(0.01);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void FSocketClientTCPSendDataThead::sendMessage(FString messageP, TArray<uint8> byteArrayP) {
|
|
if (messageP.Len() > 0)
|
|
messageQueue.Enqueue(messageP);
|
|
if (byteArrayP.Num() > 0)
|
|
byteArrayQueue.Enqueue(byteArrayP);
|
|
pauseThread(false);
|
|
}
|
|
|
|
|
|
void FSocketClientTCPSendDataThead::pauseThread(bool pause) {
|
|
paused = pause;
|
|
if (thread != nullptr)
|
|
thread->Suspend(pause);
|
|
} |