Unreal Engine 5 WebSocket-Plugin-Integration

BlueprintWebSocket-Implementierungsleitfaden • Herunterladen über Fab Marketplace

Übersicht

BlueprintWebSocket ist ein fortschrittliches asynchrones Netzwerk-Plugin für Unreal Engine. Es ermöglicht Echtzeit-Duplex-Datenübertragungen mit externen Servern unter Verwendung der WebSocket-Netzwerkarchitektur, speziell optimiert für den Aufbau von Echtzeit-Multiplayer-Lobbys, hochfrequenten Chat-Systemen und Live-Telemetrie-Schleifen in Unreal Engine 5-Umgebungen.

Laden Sie das Plugin vom Fab Marketplace herunter, um Echtzeit-Netzwerkelemente in Ihrem aktuellen Arbeitsbereich zu initialisieren.

Blueprints

Verbindung zu einem WebSocket-Server

Mit dem Latenz-Helfer-Knoten können Sie sich mit einem aktiven Netzwerk-Socket verbinden und sofort automatisierte Ausführungsketten ausführen:

Blueprint-Skript-Layout, das die WebSocket-Verbindung mithilfe des Helfer-Knotens abbildet

Erstellen Sie für benutzerdefinierte Logikstrukturen eine explizite Socket-Instanz, um Callback-Ereignisse direkt in Event-Graph-Dispatcher einzuhängen:

Fortgeschrittenes Unreal Engine Blueprint, das mit manuellen Delegaten-Zuweisungen verbindet

Daten senden

Blueprint-Knotenkonfiguration, die strukturelle String-Nachrichten an den WebSocket-Puffer weiterleitet

Automatische Wiederverbindung bei Fehler

Behandeln Sie Verbindungsabbrüche automatisch, indem Sie Wiederholungsparameter in Ihrer Basis-Knotensequenz definieren:

Blueprint-Netzwerk-Knotengruppe, die Verbindungszustands-Wiederherstellungsschleifen verwaltet

C++

Modul hinzufügen

Öffnen Sie Ihre Quell-Build-Konfigurationsdatei (<ProjectName>.Build.cs) und fügen Sie die Modulabhängigkeit zu Ihren Kompilierungsanweisungslisten hinzu:

PublicDependencyModuleNames.Add("BlueprintWebSocket");

Einbinden

Legen Sie die Interface-Typen offen, indem Sie den Wrapper-Header in Ihre Klassendatei einfügen:

#include "BlueprintWebSocketWrapper.h"

Erstellen eines neuen WebSockets

Instanziieren Sie eine Heap-Zuweisung mithilfe der Plugin-Factory-Methode:

UBlueprintWebSocket* const WebSocket = UBlueprintWebSocket::CreateWebSocket();

Konfigurieren des WebSockets

Ändern Sie Transport-Metadatenstrukturen und Authentifizierungs-Header, bevor Sie die Verbindungs-Handshake-Routine aufrufen:

// Führt die bereitgestellte Map mit der aktuellen Header-Liste zusammen.
WebSocket->SetHeaders(const TMap<FString, FString> & InHeaders);

// Fügt ein Key / Value-Paar zur Header-Liste hinzu.
WebSocket->AddHeader(const FString & Header, const FString & Value);

// Entfernt den Header aus der Header-Liste
WebSocket->RemoveHeader(const FString & HeaderToRemove);

Ereignisse mit Callbacks überwachen

Binden Sie funktionale Ziele an die asynchronen Delegaten, um Netzwerkantwort-Zustandsänderungen sicher zu empfangen:

Ereignisname Signatur Beschreibung
OnConnectedEvent void Func() Wird aufgerufen, wenn wir erfolgreich mit dem WebSocket-Server verbunden sind.
OnConnectionErrorEvent void Func(const FString & Error) Wird aufgerufen, wenn wir keine Verbindung zum WebSocket-Server herstellen konnten.
OnCloseEvent void Func(int64 StatusCode, const FString & Reason, bool bWasClean) Wird aufgerufen, wenn die Verbindung mit dem Server geschlossen wurde.
OnMessageEvent void Func(const FString & Message) Wird aufgerufen, wenn wir eine String-Nachricht empfangen haben.
OnRawMessageEvent void Func(const TArray<uint8> & Data, int32 BytesRemaining) Wird aufgerufen, wenn wir eine Binärnachricht empfangen haben.
OnMessageSentEvent void Func(const FString & Message) Wird unmittelbar nach dem Senden einer Nachricht aufgerufen.

Da diese Hooks Dynamic Multicast Delegatesverwenden, muss jede gebundene Listener-Funktion das UFUNCTION() Dekorationsmakro tragen, um im Engine-Aufrufstapel sichtbar zu bleiben:

UCLASS()
class MYGAME_API UMyClass : public UObject
{
    GENERATED_BODY()
public:
    // Die Funktion, mit der wir die Ereignisse binden
    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()
{
    // Binden Sie die Ereignisse, damit unsere Funktionen aufgerufen werden, wenn das Ereignis ausgelöst wird.
    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);
}

Hinweis: Es wird empfohlen, alle Ereignisse, die Sie verwenden werden, vor dem Verbinden zu binden.

Verbindung zum WebSocket-Server

Übergeben Sie den expliziten Endpunkt-URI und die Kommunikationsprotokoll-Teilstrings direkt in die Verbindungsverarbeitungsschleife:

WebSocket->Connect(TEXT("ws://127.0.0.1:8080/"), TEXT("ws"));

Fragen Sie Zustandsframes inline über die funktionalen Statusprüfer ab:

if (WebSocket->IsConnected())
{
    // Wir sind verbunden.
}
else
{
    // Wir sind nicht verbunden.
}

Hinweis: Sie sollten sich nicht auf IsConnected() verlassen, um die Verbindung zu handhaben, sondern auf den OnConnectedEvent -Callback.

Nachrichten senden

Übertragen Sie Informationen stromabwärts mithilfe strukturierter Strings oder direkter Speicherpuffer:

  1. void SendMessage(const FString & Message): Zum Übergeben von Text-/JSON-Datenformaten.
  2. void SendRawMessage(const TArray<uint8> & Message, const bool bIsBinary): Zum Übertragen komprimierter Strukturen oder Asset-Dateien.

Implementierungsbeispiel:

// Die Daten, die wir senden möchten, Sie können sie programmatisch abrufen.
const FString       StringMessage = TEXT("Hello Server");
const TArray<uint8> BinaryMessage = { 0, 1, 2, 3, 4, 5 };

// Senden Sie sie über unseren WebSocket.
WebSocket->SendMessage   (StringMessage);
WebSocket->SendRawMessage(BinaryMessage);

Vollständiges Beispiel

MyClass.h

#pragma once

#include "CoreMinimal.h"
#include "MyClass.generated.h"

class UBlueprintWebSocket;

/**
 * Unsere benutzerdefinierte Klasse, die einen WebSocket verwendet.
 **/
UCLASS()
class MYGAME_API UMyClass : public UObject
{
    GENERATED_BODY()
public:
    void InitializeAndConnectSocket();
private:
    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;
};

MyClass.cpp

#include "MyClass.h"
#include "BlueprintWebSocketWrapper.h"

void UMyClass::InitializeAndConnectSocket()
{
    WebSocket = UBlueprintWebSocket::CreateWebSocket();
    
    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);

    WebSocket->AddHeader(TEXT("SomeHeader"), TEXT("SomeValue"));
    WebSocket->Connect(TEXT("ws://127.0.0.1:8080/"), TEXT("ws"));
}

void UMyClass::OnConnected()
{
    UE_LOG(LogTemp, Log, TEXT("We are connected!"));
    WebSocket->SendMessage(TEXT("Hello Server!"));
}

void UMyClass::OnConnectionError(const FString & Error)
{
    UE_LOG(LogTemp, Error, TEXT("Failed to connect: %s."), *Error);
}

void UMyClass::OnClosed(int64 StatusCode, const FString & Reason, bool bWasClean)
{
    UE_LOG(LogTemp, Warning, TEXT("Connection closed: %d:%s. Clean: %d"), StatusCode, *Reason, bWasClean);
}

void UMyClass::OnMessage(const FString & Message)
{
    UE_LOG(LogTemp, Log, TEXT("New message: %s"), *Message);
}

void UMyClass::OnRawMessage(const TArray<uint8> & Data, int32 BytesRemaining)
{
    UE_LOG(LogTemp, Log, TEXT("New binary message: %d bytes and %d bytes remaining."), Data.Num(), BytesRemaining);
}

void UMyClass::OnMessageSent(const FString & Message)
{
    UE_LOG(LogTemp, Log, TEXT("We just sent %s to the server."), *Message);
}

Fehlerbehebung

Verbindung fehlgeschlagen: SSL-Fehler: Lokales Ausstellerzertifikat kann nicht abgerufen werden

Dieses Netzwerksicherheitsproblem tritt auf, weil öffentliche Validierungs-Stammzertifizierungsstellen im Plattform-Bundle in vollständig gekochten Spiel-Distributionen ausgelassen werden. Beheben Sie die Integrität des Distributionspakets mit diesen Schritten:

  1. Platzieren Sie Ihre aktive Autorisierungs-Zertifizierungsstellendatei (.pem-Format) in Ihrem Projektquellpfad: <Project>/Content/Certificates/cacert.pem.
  2. Legen Sie das Ziel-Unterverzeichnis für den Plattform-Packager über Projekteinstellungen >Packaging >Zusätzliche Nicht-Asset-Verzeichnisse zum Kopieren Listen-Arrays offen.

Support

Für Funktionsempfehlungen oder funktionale Support-Updates öffnen Sie ein Entwickler-Anfrage-Ticket direkt bei unserem Core-Engineering-Desk unter: pandores.marketplace@gmail.com.