Skip to content

Instantly share code, notes, and snippets.

@HavenRemix
Last active March 17, 2024 03:56
Show Gist options
  • Save HavenRemix/04749e370ef8c7d6fd17f4924aa28d81 to your computer and use it in GitHub Desktop.
Save HavenRemix/04749e370ef8c7d6fd17f4924aa28d81 to your computer and use it in GitHub Desktop.
Shows a basic example of how to use websockets in UE4 probably UE5
#include "Interfaces/IHttpResponse.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Runtime/Online/HTTP/Public/Http.h"
#include "IWebSocket.h"
#include "IWebSocketsManager.h"
#include "WebSocketsModule.h"
//Those are all the related includes I have not sure which ones you need for the websocket. The last three are required
//.h
const FString MatchmakingWebSocketConnectURL = "wss://<endpoint-id>.execute-api.us-west-1.amazonaws.com/<stage-name>";
//The module to connect and maintain websockets need only one
FWebSocketsModule* WebSocketModule;
//Per websocket have to be implemented seperately in case you need to connect to multiple I only implement one this is just for example
TSharedPtr<IWebSocket> PollMatchmakingWebSocket;
TSharedPtr<IWebSocket> MatchmakingWebSocket;
TSharedPtr<IWebSocket> PlayerWebSocket;
//.cpp
void FGameLiftHandler::Construct(class UVILEGameInstance* InGameInstance)
{
//Initialize you websocket module (this should be done either in the constructor or begin play, im not sure, but this function is the equivalent of begin play for this class)
WebSocketModule = &FWebSocketsModule::Get();
GameInstance = InGameInstance;
}
void FGameLiftHandler::ConnectToMatchmakingWebSocket()
{
//This is a custom class you would use BindUObject or something
MatchmakingWebSocket = WebSocketModule->CreateWebSocket(MatchmakingWebSocketConnectURL, TEXT("ws")); //I use ws here because the line above has the wss:// protocol
MatchmakingWebSocket->OnConnected().AddRaw(this, &FGameLiftHandler::OnMatchmakingWebSocketConnectionSuccess);
MatchmakingWebSocket->OnConnectionError().AddRaw(this, &FGameLiftHandler::OnMatchmakingWebSocketConnectionError);
MatchmakingWebSocket->OnClosed().AddRaw(this, &FGameLiftHandler::OnMatchmakingWebSocketDisconnectionSuccess);
MatchmakingWebSocket->OnMessage().AddRaw(this, &FGameLiftHandler::OnMatchmakingWebSocketMessageReceived);
MatchmakingWebSocket->Connect();
}
void FGameLiftHandler::DisconnectFromMatchmakingWebSocket()
{
//Make sure the socket is connected as an optimazation
if (MatchmakingWebSocket->IsConnected())
{
//Disconnects the socket
MatchmakingWebSocket->Close();
}
}
void FGameLiftHandler::OnMatchmakingWebSocketConnectionSuccess()
{
//Make sure the socket is connected as an optimazation otherwise return
if (!MatchmakingWebSocket->IsConnected())
{
return;
}
UE_LOG(LogOnline, Verbose, TEXT("Connected to the matchmaking websocket"));
//Do things directly after the socket connects
//Persoanlly I wrote the connection Id to the data base so the server could send things back to it
}
void FGameLiftHandler::OnMatchmakingWebSocketConnectionError(const FString& Error)
{
UE_LOG(LogOnline, Verbose, TEXT("Connected to the matchmaking websocket failed"));
}
void FGameLiftHandler::OnMatchmakingWebSocketDisconnectionSuccess(int32 StatusCode, const FString& Reason, bool bWasClean)
{
UE_LOG(LogOnline, Verbose, TEXT("Disconnected to the websocket"));
}
void FGameLiftHandler::OnMatchmakingWebSocketMessageReceived(const FString& Message)
{
/**
* This function is called when the server sends something to the websocket
* This particular funciton recieves messages as strings
* There is also a binary version but I'm not sure how to use that, you can read the docs though
* The code below transforms the message to a json object
* If you use the code below make sure you JSON.stringify the body in your response object in the lambdas
*/
UE_LOG(LogTemp, Warning, TEXT("Message: %s"), *Message);
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Message);
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
TSharedPtr<FJsonObject> Response = JsonObject->GetObjectField("ResponseObject");
//You can then use general JSON methods
}
}
void FGameLiftHandler::MaintainConnection()
{
/**
* In API Gateway websockets can only last idle for 10 minutes
* So I wrote this funtion which executes every under 10 minutes on a timer
* The timer logic isnt here that was set in the constructor (This is a custom class, you would do this in begin play)
* "MaintainConnection" is a route I made in API gateway
* This function also shows how you can send JSON objects to the websocket
*/
TSharedPtr<FJsonObject> RequestObj = MakeShareable(new FJsonObject());
RequestObj->SetStringField("action", "MaintainConnection");
FString RequestBody;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&RequestBody);
if (FJsonSerializer::Serialize(RequestObj.ToSharedRef(), Writer))
{
MatchmakingWebSocket->Send(RequestBody);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment