BlueprintWebSocket - Documentation
Using the helper node, it's really fast to connect to a WebSocket server:
You can also use the raw functions to have the same access as if you were coding in C++. This is longer but allows you to bind functions to events:
You can easily automatically reconnect to your server when a network error happens with the helper nodes:
Open your project's <ProjectName>.Build.cs
and add the following line of code:
PublicDependencyModuleNames.Add("BlueprintWebSocket");
BlueprintWebSocket requires you to include only one file:
#include "BlueprintWebSocketWrapper.h"
BlueprintWebSocket provides an easy way to create a socket:
UBlueprintWebSocket* const WebSocket = UBlueprintWebSocket::CreateWebSocket();
Now that the WebSocket is created, we can configure it to talk with our WebSocket server. Here is an exhaustive list of functions available for modifying the headers sent during the connection:
// Merges the provided map with the current header list.
WebSocket->SetHeaders(const TMap<FString, FString> & InHeaders);
// Adds a pair Key / Value to the list of headers.
WebSocket->AddHeader(const FString & Header, const FString & Value);
// Removes the header from the header list
WebSocket->RemoveHeader(const FString & HeaderToRemove);
As the WebSocket is asynchronous, we need to listen to events to react to connection, connection error or messages. Here is a list of the events and their signature:
Event Name | Signature | Description |
---|---|---|
OnConnectedEvent |
void Func() |
Called when we are successfully connected to the WebSocket Server. |
OnConnectionErrorEvent |
void Func(const FString & Error) |
Called when we failed to connect to the WebSocket server. |
OnCloseEvent |
void Func(int64 StatusCode, const FString & Reason, bool bWasClean) |
Called when the connection with the server has been closed. |
OnMessageEvent |
void Func(const FString & Message) |
Called when we received a string message. |
OnRawMessageEvent |
void Func(const TArray<uint8> & Data, int32 BytesRemaining) |
Called when we received a binary message. |
OnMessageSentEvent |
void Func(const FString & Message) |
Called just after we sent a message. |
The WebSocket events are Dynamic Multicast Delegates
, it requires the function bound to be declared as UFUNCTION()
:
UCLASS()
class MYGAME_API UMyClass : public UObject
{
GENERATED_BODY()
public:
// The function we use to bind the events
void BindEvents();
private:
// Callbacks
UFUNCTION() void OnConnected();
UFUNCTION() void OnConnectionError(const FString & Error);
UFUNCTION() void OnClosed(int64 StatusCode, const FString & Reason, bool bWasClean);
UFUNCTION() void OnMessage(const FString & Message);
UFUNCTION() void OnRawMessage(const TArray<uint8> & Data, int32 BytesRemaining);
UFUNCTION() void OnMessageSent(const FString & Message);
private:
UPROPERTY()
UBlueprintWebSocket* WebSocket;
};
void UMyClass::BindEvents()
{
// Bind the events so our functions are called when the event is triggered.
WebSocket->OnConnectedEvent .AddDynamic(this, &UMyClass::OnConnected);
WebSocket->OnConnectionErrorEvent.AddDynamic(this, &UMyClass::OnConnectionError);
WebSocket->OnCloseEvent .AddDynamic(this, &UMyClass::OnClosed);
WebSocket->OnMessageEvent .AddDynamic(this, &UMyClass::OnMessage);
WebSocket->OnRawMessageEvent .AddDynamic(this, &UMyClass::OnRawMessage);
WebSocket->OnMessageSentEvent .AddDynamic(this, &UMyClass::OnMessageSent);
}
It is recommended to bind all events you will use before connecting. |
---|
To establish the connection with your WebSocket server, you have to call void Connect(const FString & Url, const FString & Protocol)
:
WebSocket->Connect(TEXT("ws://myserver.com:8080/"), TEXT("ws"));
You can then check at any moment if you are connected with bool IsConnected() const
:
if (WebSocket->IsConnected())
{
// We are connected.
}
else
{
// We are not connected.
}
You shouldn't rely on IsConnected() to handle connection but on the OnConnectedEvent callback. |
---|
To send messages to your server, you have two possibilities:
void SendMessage(const FString & Message)
To send String messages.void SendRawMessage(const TArray<uint8> & Message, const bool bIsBinary)
To send raw (binary) messages.
Their use is pretty similar:
// The data we want to send, you can get it programmatically.
const FString StringMessage = TEXT("Hello Server");
const TArray<uint8> BinaryMessage = { 0, 1, 2, 3, 4, 5 };
// Send it through our WebSocket.
WebSocket->SendMessage (StringMessage);
WebSocket->SendRawMessage(BinaryMessage);
#pragma once
#include "CoreMinimal"
#include "MyClass.generated.h"
// Forward declaration. You can as well just include
// BlueprintWebSocketWrapper.h before MyClass.generated.h.
class UBlueprintWebSocket;
/**
* Our custom class that uses a WebSocket.
**/
UCLASS()
class <MYGAME>_API UMyClass : public UObject
{
GENERATED_BODY()
public:
// The function we use to create and connect our socket
// to the WebSocket server.
void InitializeAndConnectSocket();
private:
// Callbacks
UFUNCTION()
void OnConnected();
UFUNCTION()
void OnConnectionError(const FString & Error);
UFUNCTION()
void OnClosed(int64 StatusCode, const FString & Reason, bool bWasClean);
UFUNCTION()
void OnMessage(const FString & Message);
UFUNCTION()
void OnRawMessage(const TArray<uint8> & Data, int32 BytesRemaining);
UFUNCTION()
void OnMessageSent(const FString & Message);
private:
// The WebSocket, marking it as UPROPERTY prenvents it
// from being garbage collected as actions are latent.
UPROPERTY()
UBlueprintWebSocket* WebSocket;
};
#include "MyClass.h"
#include "BlueprintWebSocketWrapper.h"
void UMyClass::InitializeAndConnectSocket()
{
// Create our new BlueprintWebsocket object.
WebSocket = UBlueprintWebSocket::CreateWebSocket();
// Bind the events so our functions are called when the events are triggered.
WebSocket->OnConnectedEvent .AddDynamic(this, &UMyClass::OnConnected);
WebSocket->OnConnectionErrorEvent.AddDynamic(this, &UMyClass::OnConnectionError);
WebSocket->OnCloseEvent .AddDynamic(this, &UMyClass::OnClosed);
WebSocket->OnMessageEvent .AddDynamic(this, &UMyClass::OnMessage);
WebSocket->OnRawMessageEvent .AddDynamic(this, &UMyClass::OnRawMessage);
WebSocket->OnMessageSentEvent .AddDynamic(this, &UMyClass::OnMessageSent);
// Add our headers.
WebSocket->AddHeader(TEXT("SomeHeader"), TEXT("SomeValue"));
// And we connect.
WebSocket->Connect(TEXT("ws://localhost:8080/"), TEXT("ws"));
}
void UMyClass::OnConnected()
{
// We successfully connected.
UE_LOG(LogTemp, Log, TEXT("We are connected!"));
// It's safe here to send some data to our server.
WebSocket->SendMessage(TEXT("Hello Server!"));
}
void UMyClass::OnConnectionError(const FString & Error)
{
// Connection failed.
UE_LOG(LogTemp, Error, TEXT("Failed to connect: %s."), *Error);
}
void UMyClass::OnClosed(int64 StatusCode, const FString & Reason, bool bWasClean)
{
// The connection has been closed.
UE_LOG(LogTemp, Warning, TEXT("Connection closed: %d:%s. Clean: %d"), StatusCode, *Reason, bWasClean);
}
void UMyClass::OnMessage(const FString & Message)
{
// The server sent us a message
UE_LOG(LogTemp, Log, TEXT("New message: %s"), *Message);
}
void UMyClass::OnRawMessage(const TArray<uint8> & Data, int32 BytesRemaining)
{
// We received a binary message.
UE_LOG(LogTemp, Log, TEXT("New binary message: %d bytes and %d bytes remaining."), Data.Num(), BytesRemaining);
}
void UMyClass::OnMessageSent(const FString & Message)
{
// We just sent a message
UE_LOG(LogTemp, Log, TEXT("We just sent %s to the server."), *Message);
}
This error happens because the SSL certificate is not included in the packaged version of your game. To add the certificate to the packaged version, you need to do the following:
- Copy the .pem certificate file to the location
<Project>/Content/Certificates/cacert.pem
. - Add the certificate to the files to copy into the packaged build into
Settings
>Packaging
>Packaging
>Additional Non-Assets Directories To Copy
.
If you need help, have a feature request or experience troubles, please contact us at [email protected].