494 lines
19 KiB
C++
494 lines
19 KiB
C++
// Copyright 2018-current Getnamo. All Rights Reserved
|
|
|
|
|
|
#pragma once
|
|
|
|
#include "Components/ActorComponent.h"
|
|
#include "SocketIONative.h"
|
|
#include "Runtime/Engine/Classes/Engine/LatentActionManager.h"
|
|
#include "SocketIOClientComponent.generated.h"
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FSIOCEventSignature);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSIOCSocketEventSignature, FString, Namespace);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FSIOCOpenEventSignature, FString, SocketId, FString, SessionId, bool, bIsReconnection);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSIOCCloseEventSignature, TEnumAsByte<ESIOConnectionCloseReason>, Reason);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSIOCEventJsonSignature, FString, EventName, class USIOJsonValue*, EventData);
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FSIOConnectionProblemSignature, int32, Attempts, int32, NextAttemptInMs, float, TimeSinceConnected);
|
|
|
|
//For Direct Delegate Event Bind
|
|
DECLARE_DYNAMIC_DELEGATE_OneParam(FSIOJsonValueSignature, USIOJsonValue*, EventData);
|
|
|
|
UCLASS(BlueprintType, ClassGroup = "Networking", meta = (BlueprintSpawnableComponent))
|
|
class SOCKETIOCLIENT_API USocketIOClientComponent : public UActorComponent
|
|
{
|
|
GENERATED_UCLASS_BODY()
|
|
public:
|
|
|
|
//Async events
|
|
|
|
/** On generic bound event received. Requires Bind Event to Generic Event to be called before. Will not receive Bind Event To Function events. */
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOCEventJsonSignature OnGenericEvent;
|
|
|
|
/** Received on socket.io connection established. */
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOCOpenEventSignature OnConnected;
|
|
|
|
/**
|
|
* Received on socket.io connection disconnected. This may never get
|
|
* called in default settings, see OnConnectionProblems event for details.
|
|
*/
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOCCloseEventSignature OnDisconnected;
|
|
|
|
/**
|
|
* Received when connection problems arise. In default settings the
|
|
* connection will keep repeating trying to reconnect an infinite
|
|
* amount of times and you may never get OnDisconnected callback
|
|
* unless you call it.
|
|
*/
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOConnectionProblemSignature OnConnectionProblems;
|
|
|
|
/** Received on having joined namespace. */
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOCSocketEventSignature OnSocketNamespaceConnected;
|
|
|
|
/** Received on having left namespace. */
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOCSocketEventSignature OnSocketNamespaceDisconnected;
|
|
|
|
/** Received on connection failure. */
|
|
UPROPERTY(BlueprintAssignable, Category = "SocketIO Events")
|
|
FSIOCEventSignature OnFail;
|
|
|
|
|
|
/**
|
|
* Default connection params used on e.g. on begin play. Can be updated and re-used on custom connection.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
FSIOConnectParams URLParams;
|
|
|
|
/**
|
|
* Will force using TLS even if url doesn't have https:// prepend.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
bool bForceTLS;
|
|
|
|
/**
|
|
* If true, all your bound events will unbind on disconnect.
|
|
* Useful for cleanup if typically binding on connection and there
|
|
* are no early event binds (before connection).
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
bool bUnbindEventsOnDisconnect;
|
|
|
|
/**
|
|
* If using a TLS url (or if forced) and setting this to false will not verify
|
|
* the authenticity of the SSL certificate (i.e. asio::ssl::verify_none).
|
|
*
|
|
* NOTE: Certification verification is currently not implemented; setting to true will
|
|
* always fail verification.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
bool bShouldVerifyTLSCertificate;
|
|
|
|
/** If true will auto-connect on begin play to address specified in AddressAndPort. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
bool bShouldAutoConnect;
|
|
|
|
/** Delay between reconnection attempts */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
int32 ReconnectionDelayInMs;
|
|
|
|
/**
|
|
* Number of times the connection should try before giving up.
|
|
* Default: infinity, this means you never truly disconnect, just suffer connection problems
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
int32 MaxReconnectionAttempts;
|
|
|
|
/** Optional parameter to limit reconnections by elapsed time. Default: infinity. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
float ReconnectionTimeout;
|
|
|
|
FDateTime TimeWhenConnectionProblemsStarted;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Connection Properties")
|
|
bool bVerboseConnectionLog;
|
|
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Scope Properties")
|
|
bool bLimitConnectionToGameWorld;
|
|
|
|
/**
|
|
* Toggle which enables plugin scoped connections.
|
|
* If you enable this the connection will remain until you manually call disconnect
|
|
* or close the app. The latest connection with the same PluginScopedId will use the same connection
|
|
* as the previous one and receive the same events.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Scope Properties")
|
|
bool bPluginScopedConnection;
|
|
|
|
/** If you leave this as is all plugin scoped connection components will share same connection*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SocketIO Scope Properties")
|
|
FString PluginScopedId;
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "SocketIO Connection Properties")
|
|
bool bIsConnected;
|
|
|
|
/** When connected this session id will be valid and contain a unique Id. */
|
|
UPROPERTY(BlueprintReadOnly, Category = "SocketIO Connection Properties")
|
|
FString SessionId;
|
|
|
|
/** Each new connection is assigned a random 20-characters identifier. This identifier is synced with the value on the client-side. */
|
|
UPROPERTY(BlueprintReadOnly, Category = "SocketIO Connection Properties")
|
|
FString SocketId;
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "SocketIO Connection Properties")
|
|
bool bIsHavingConnectionProblems;
|
|
|
|
/** If this component has been statically initialized. Largely exposed for traceability. */
|
|
UPROPERTY(BlueprintReadOnly, Category = "SocketIO Connection Properties")
|
|
bool bStaticallyInitialized;
|
|
|
|
/**
|
|
* Connect to a socket.io server, optional method if auto-connect is set to true.
|
|
* Query and headers are defined by a {'stringKey':'stringValue'} SIOJson Object
|
|
*
|
|
* @param AddressAndPort the address in URL format with port, if left empty it will
|
|
* use current URLParams for all inputs.
|
|
* @param Path optional ws:// trailing path for socket.io connection
|
|
* @param Query http query as a SIOJsonObject with string keys and values
|
|
* @param Headers http header as a SIOJsonObject with string keys and values
|
|
* @param Auth socket.io authorization option as a SIOJsonObject with string keys and values
|
|
*
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void Connect( const FString& InAddressAndPort = TEXT(""),
|
|
const FString& InPath = TEXT("socket.io"),
|
|
const FString& InAuthToken = TEXT(""),
|
|
USIOJsonObject* Query = nullptr,
|
|
USIOJsonObject* Headers = nullptr);
|
|
|
|
/**
|
|
* Connect to a socket.io server, optional method if auto-connect is set to true.
|
|
*
|
|
* @param InURLParams - A struct holding address&port, path, headers, query, and auth params
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void ConnectWithParams(const FSIOConnectParams& InURLParams);
|
|
|
|
/**
|
|
* Disconnect from current socket.io server. This is an asynchronous action,
|
|
* subscribe to OnDisconnected to know when you can safely continue from a
|
|
* disconnected state.
|
|
*
|
|
* @param AddressAndPort the address in URL format with port
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void Disconnect();
|
|
|
|
void SyncDisconnect();
|
|
|
|
/**
|
|
* Join a desired namespace. Keep in mind that emitting to a namespace will auto-join it
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void JoinNamespace(const FString& Namespace);
|
|
|
|
/**
|
|
* Leave a specified namespace. Should stop listening to events on given namespace.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void LeaveNamespace(const FString& Namespace);
|
|
|
|
//
|
|
//Blueprint Functions
|
|
//
|
|
|
|
/**
|
|
* Emit an event with a JsonValue message
|
|
*
|
|
* @param Name Event name
|
|
* @param Message SIOJJsonValue
|
|
* @param Namespace Namespace within socket.io
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void Emit(const FString& EventName, USIOJsonValue* Message = nullptr, const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* Emit an event with a JsonValue message with a callback function defined by CallBackFunctionName
|
|
*
|
|
* @param Name Event name
|
|
* @param Message SIOJsonValue
|
|
* @param CallbackFunctionName Name of the optional callback function with signature (String, SIOJsonValue)
|
|
* @param Target Optional, defaults to caller self. Change to delegate function callback to another class.
|
|
* @param Namespace Namespace within socket.io
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions", meta = (WorldContext = "WorldContextObject"))
|
|
void EmitWithCallBack( const FString& EventName,
|
|
USIOJsonValue* Message = nullptr,
|
|
const FString& CallbackFunctionName = FString(""),
|
|
UObject* Target = nullptr,
|
|
const FString& Namespace = TEXT("/"),
|
|
UObject* WorldContextObject = nullptr);
|
|
|
|
|
|
/**
|
|
* Emit an event with a JsonValue message with a result callback directly into the event graph. This cannot be called from within blueprint functions.
|
|
*
|
|
* @param Name Event name
|
|
* @param LatentInfo Graph callback reference
|
|
* @param Result Graph callback result SIOJsonValue
|
|
* @param Message SIOJsonValue
|
|
* @param Namespace Namespace within socket.io
|
|
*/
|
|
UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "LatentInfo"), Category = "SocketIO Functions")
|
|
void EmitWithGraphCallBack( const FString& EventName,
|
|
struct FLatentActionInfo LatentInfo,
|
|
USIOJsonValue*& Result,
|
|
USIOJsonValue* Message = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
|
|
|
|
/**
|
|
* Bind an event directly to a matching delegate. Drag off from red box or
|
|
* use create event option.
|
|
*
|
|
* @param EventName Event name
|
|
* @param CallbackDelegate Delegate that needs to be bound
|
|
* @param Namespace Optional namespace, defaults to default namespace
|
|
* @param ThreadOverride Optional override to receive event on specified thread. Note NETWORK thread is lower latency but unsafe for a lot of blueprint use. Use with CAUTION.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void BindEventToDelegate( const FString& EventName,
|
|
const FSIOJsonValueSignature& CallbackDelegate,
|
|
const FString& Namespace = TEXT("/"),
|
|
ESIOThreadOverrideOption ThreadOverride = USE_DEFAULT);
|
|
|
|
/**
|
|
* Bind an event, then respond to it with 'OnGenericEvent' multi-cast delegate.
|
|
* If you want functions or custom events to receive the event, use Bind Event To Function.
|
|
*
|
|
* @param EventName Event name
|
|
* @param Namespace Optional namespace, defaults to default namespace
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void BindEventToGenericEvent(const FString& EventName, const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* Bind an event to a function with the given name.
|
|
* Expects a String message signature which can be decoded from JSON into SIOJsonObject
|
|
*
|
|
* @param EventName Event name
|
|
* @param FunctionName The function that gets called when the event is received
|
|
* @param Target Optional, defaults to caller self. Change to delegate to another class.
|
|
* @param Namespace Optional namespace, defaults to default namespace
|
|
* @param ThreadOverride Optional override to receive event on specified thread. Note NETWORK thread is lower latency but unsafe for a lot of blueprint use. Use with CAUTION.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions", meta = (WorldContext = "WorldContextObject"))
|
|
void BindEventToFunction( const FString& EventName,
|
|
const FString& FunctionName,
|
|
UObject* Target,
|
|
const FString& Namespace = TEXT("/"),
|
|
ESIOThreadOverrideOption ThreadOverride = USE_DEFAULT,
|
|
UObject* WorldContextObject = nullptr);
|
|
|
|
/**
|
|
* Unbind an event from whatever it was bound to (safe to call if not already bound)
|
|
*
|
|
* @param EventName Event name
|
|
* @param Namespace Optional namespace, defaults to default namespace
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "SocketIO Functions")
|
|
void UnbindEvent(const FString& EventName, const FString& Namespace = TEXT("/"));
|
|
|
|
|
|
//
|
|
//C++ functions
|
|
//
|
|
|
|
/**
|
|
* Connect to a socket.io server, optional method if auto-connect is set to true.
|
|
* Query and headers are defined by a {'stringKey':'stringValue'} FJsonObjects
|
|
*
|
|
* @param AddressAndPort the address in URL format with port
|
|
* @param Path the path of the socketio server (ex: "socket.io"
|
|
* @param Query http query as a FJsonObject with string keys and values
|
|
* @param Headers http header as a FJsonObject with string keys and values
|
|
*
|
|
*/
|
|
void ConnectNative( const FString& InAddressAndPort,
|
|
const FString& InPath = TEXT("socket.io"),
|
|
const FString& InAuthToken = TEXT(""),
|
|
const TSharedPtr<FJsonObject>& Query = nullptr,
|
|
const TSharedPtr<FJsonObject>& Headers = nullptr);
|
|
|
|
|
|
/**
|
|
* Emit an event with a JsonValue message
|
|
*
|
|
* @param EventName Event name
|
|
* @param Message FJsonValue
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
const TSharedPtr<FJsonValue>& Message = nullptr,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with a Json Object message
|
|
*
|
|
* @param EventName Event name
|
|
* @param ObjectMessage FJsonObject
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
const TSharedPtr<FJsonObject>& ObjectMessage = nullptr,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with a string message
|
|
*
|
|
* @param EventName Event name
|
|
* @param StringMessage Message in string format
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
const FString& StringMessage = FString(),
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with a string message
|
|
*
|
|
* @param EventName Event name
|
|
* @param StringMessage Message in string format
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
const SIO_TEXT_TYPE StringMessage = TEXT(""),
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with a number (double) message
|
|
*
|
|
* @param EventName Event name
|
|
* @param NumberMessage Message in double format
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
double NumberMessage,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with a bool message
|
|
*
|
|
* @param EventName Event name
|
|
* @param BooleanMessage Message in bool format
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
bool BooleanMessage,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with a binary message
|
|
*
|
|
* @param EventName Event name
|
|
* @param BinaryMessage Message in an TArray of uint8
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
const TArray<uint8>& BinaryMessage,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with an array message
|
|
*
|
|
* @param EventName Event name
|
|
* @param ArrayMessage Message in an TArray of FJsonValues
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
const TArray<TSharedPtr<FJsonValue>>& ArrayMessage,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* (Overloaded) Emit an event with an UStruct message
|
|
*
|
|
* @param EventName Event name
|
|
* @param Struct UStruct type usually obtained via e.g. FMyStructType::StaticStruct()
|
|
* @param StructPtr Pointer to the actual struct memory e.g. &MyStruct
|
|
* @param CallbackFunction Optional callback TFunction
|
|
* @param Namespace Optional Namespace within socket.io
|
|
*/
|
|
void EmitNative(const FString& EventName,
|
|
UStruct* Struct,
|
|
const void* StructPtr,
|
|
TFunction< void(const TArray<TSharedPtr<FJsonValue>>&)> CallbackFunction = nullptr,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
/**
|
|
* Call function callback on receiving socket event. C++ only.
|
|
*
|
|
* @param EventName Event name
|
|
* @param TFunction Lambda callback, JSONValue
|
|
* @param Namespace Optional namespace, defaults to default namespace
|
|
* @param ThreadOverride Optional override to receive event on specified thread. Note NETWORK thread is lower latency but unsafe for a lot of blueprint use. Use with CAUTION.
|
|
*/
|
|
void OnNativeEvent( const FString& EventName,
|
|
TFunction< void(const FString&, const TSharedPtr<FJsonValue>&)> CallbackFunction,
|
|
const FString& Namespace = TEXT("/"),
|
|
ESIOThreadOverrideOption ThreadOverride = USE_DEFAULT);
|
|
|
|
/**
|
|
* Call function callback on receiving binary event. C++ only.
|
|
*
|
|
* @param EventName Event name
|
|
* @param TFunction Lambda callback, raw flavor
|
|
* @param Namespace Optional namespace, defaults to default namespace
|
|
*/
|
|
void OnBinaryEvent( const FString& EventName,
|
|
TFunction< void(const FString&, const TArray<uint8>&)> CallbackFunction,
|
|
const FString& Namespace = TEXT("/"));
|
|
|
|
|
|
/** Called by SocketIOFunctionLibrary to initialize statically constructed components. */
|
|
void StaticInitialization(UObject* WorldContextObject, bool bValidOwnerWorld);
|
|
|
|
virtual void InitializeComponent() override;
|
|
virtual void UninitializeComponent() override;
|
|
virtual void BeginPlay() override;
|
|
|
|
~USocketIOClientComponent();
|
|
|
|
protected:
|
|
void SetupCallbacks();
|
|
void ClearCallbacks();
|
|
void InitializeNative();
|
|
|
|
bool CallBPFunctionWithResponse(UObject* Target, const FString& FunctionName, TArray<TSharedPtr<FJsonValue>> Response);
|
|
bool CallBPFunctionWithMessage(UObject* Target, const FString& FunctionName, TSharedPtr<FJsonValue> Message);
|
|
|
|
FCriticalSection AllocationSection;
|
|
TSharedPtr<FSocketIONative> NativeClient;
|
|
};
|