153 lines
3.9 KiB
C++
153 lines
3.9 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "LuckyDataTransferSubsystem.h"
|
|
#include "JsonUtilities.h"
|
|
#include "JsonObjectConverter.h"
|
|
#include "WebSocketsModule.h"
|
|
#include "Slate/SceneViewport.h"
|
|
|
|
ULuckyDataTransferSubsystem::ULuckyDataTransferSubsystem()
|
|
{
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|
{
|
|
Super::Initialize(Collection);
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Deinitialize()
|
|
{
|
|
Super::Deinitialize();
|
|
|
|
if (Socket.IsValid() && Socket->IsConnected())
|
|
{
|
|
Socket->Close();
|
|
}
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Internal_OpenWebsocket(const FString& URL, const FString& Protocol)
|
|
{
|
|
const FString NewUrl = URL.IsEmpty() ? TEXT("ws://127.0.0.1:3000/ws") : URL;
|
|
const FString NewProtocol = Protocol.IsEmpty() ? TEXT("ws") : Protocol;
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("Opening WebSocket URL: %s"), *NewUrl);
|
|
|
|
if (!FModuleManager::Get().IsModuleLoaded("WebSockets"))
|
|
{
|
|
FModuleManager::Get().LoadModule("WebSockets");
|
|
}
|
|
|
|
Socket = FWebSocketsModule::Get().CreateWebSocket(NewUrl);
|
|
Socket->Connect();
|
|
|
|
//Set up callbacks
|
|
Socket->OnConnectionError().AddUObject(this, &ULuckyDataTransferSubsystem::Callback_OnConnectionError);
|
|
Socket->OnConnected().AddUObject(this, &ULuckyDataTransferSubsystem::Callback_OnConnected);
|
|
Socket->OnMessage().AddUObject(this, &ULuckyDataTransferSubsystem::Callback_OnMessage);
|
|
}
|
|
|
|
//Callbacks
|
|
void ULuckyDataTransferSubsystem::Callback_OnConnected()
|
|
{
|
|
if (OnSocketReady.IsBound())
|
|
{
|
|
OnSocketReady.Broadcast(true);
|
|
UE_LOG(LogTemp, VeryVerbose, TEXT("WebSocket connected successfully"));
|
|
}
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Callback_OnConnectionError(const FString& Error)
|
|
{
|
|
UE_LOG(LogTemp, VeryVerbose, TEXT("Websocket connection error: %s"), *Error)
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Callback_OnMessage(const FString& Message)
|
|
{
|
|
if (!Message.IsEmpty())
|
|
{
|
|
CommandReady(InterpretData(Message));
|
|
return;
|
|
}
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("The message received from the websocket is invalid"));
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Internal_OnMessageSent(const FString& Message)
|
|
{
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::Callback_OnConnectionClosed()
|
|
{
|
|
}
|
|
|
|
//Blueprint Exposed Implementation
|
|
void ULuckyDataTransferSubsystem::ConnectToWebsocket(const FString& URL, const FString& Protocol)
|
|
{
|
|
Internal_OpenWebsocket(URL, Protocol);
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::SendMessage(const FString& Message)
|
|
{
|
|
if (Socket.IsValid() && Socket->IsConnected())
|
|
{
|
|
Socket->Send(Message);
|
|
return;
|
|
}
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("WebSocket outgoing message failed"));
|
|
}
|
|
|
|
FPayload ULuckyDataTransferSubsystem::InterpretData(const FString& Message)
|
|
{
|
|
FPayload Payload = FPayload();
|
|
|
|
if (!Message.IsEmpty())
|
|
{
|
|
TSharedPtr<FJsonObject> JsonObj;
|
|
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Message);
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JsonObj) && JsonObj.IsValid())
|
|
{
|
|
for (auto& Elem : JsonObj->Values)
|
|
{
|
|
FCommand Command = FCommand();
|
|
Command.Key = FString(Elem.Key);
|
|
Command.Value = Elem.Value->AsNumber();
|
|
|
|
Payload.Commands.Add(Command);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Payload;
|
|
}
|
|
|
|
void ULuckyDataTransferSubsystem::CommandReady(const FPayload& Payload)
|
|
{
|
|
if (OnCommandReady.IsBound())
|
|
{
|
|
OnCommandReady.Broadcast(Payload);
|
|
}
|
|
}
|
|
|
|
//Blueprint Callable function - Use CreateJsonPayload_Observation in C++
|
|
bool ULuckyDataTransferSubsystem::MakeObservationPayload(const FObservationPayload& Data)
|
|
{
|
|
return CreateJsonPayload_Observation(Data);
|
|
}
|
|
|
|
bool ULuckyDataTransferSubsystem::CreateJsonPayload_Observation(const FObservationPayload& Data)
|
|
{
|
|
bool bSuccess = false;
|
|
ObservationPayloadString = FString();
|
|
|
|
if (!Data.ObservationState.IsEmpty())
|
|
{
|
|
FJsonObjectConverter::UStructToJsonObjectString(Data, ObservationPayloadString);
|
|
UE_LOG(LogTemp, Warning, TEXT("Payload observation: %s"), *ObservationPayloadString);
|
|
bSuccess = true;
|
|
}
|
|
|
|
return bSuccess;
|
|
} |