Registering Handlers

Note

The following is an advanced feature and requires editing the C++ source code of the plugin.

Strix currently has no generic handler for Relay messages, so these need to be handled by a custom implementation.

The following sample implementation adds two new functions to the StrixBlueprintFunctionLibrary and to the StrixNetworkFacade which the library uses. These functions are for registering a Blueprint function as a handler for the room and direct Relay messages respectively.

This method should not need to be changed for most cases. One thing to note is Relay messages can be of different types, and so the object conversion step in the last two functions below should be changed to the applicable types.

Function Setup

// StrixBlueprintFunctionLibrary.h

/** Registers a handler to call when a Relay is received
  *  @param handler The callback to call when notification received
  *  @param channelId       The channel to listen on
  */
UFUNCTION(BlueprintCallable, Category = "StrixBPLibrary", meta = (WorldContext = "WorldContextObject"))
    static void RegisterStrixRoomRelayNotificationHandler(const UObject * WorldContextObject, const FStrixRoomRelayNotificationDelegate& handler, int32 channelId);

/** Registers a handler to call when a direct Relay is received
  *  @param handler The callback to call when notification received
  *  @param channelId       The channel to listen on
  */
UFUNCTION(BlueprintCallable, Category = "StrixBPLibrary", meta = (WorldContext = "WorldContextObject"))
    static void RegisterStrixDirectRelayNotificationHandler(const UObject * WorldContextObject, const FStrixDirectRelayNotificationDelegate& handler, int32 channelId);
// StrixBlueprintFunctionLibrary.cpp

void UStrixBlueprintFunctionLibrary::RegisterStrixRoomRelayNotificationHandler(const UObject * WorldContextObject, const FStrixRoomRelayNotificationDelegate& handler, int32 channelId)
{
    // Get the network facade
    UStrixNetworkFacade* strixNetwork = UStrixNetworkFacade::GetInstance(WorldContextObject);

    // Check it exists
    if (!strixNetwork)
    {
        UE_LOG(LogStrix, Log, TEXT("StrixBlueprintFunctionLibrary::RegisterStrixRoomRelayNotificationHandler - Strix network is not initialized."));
        return;
    }

    // Call the register function
    strixNetwork->RegisterRelayNotificationHandler(handler, channelId);
}

void UStrixBlueprintFunctionLibrary::RegisterStrixDirectRelayNotificationHandler(const UObject * WorldContextObject, const FStrixDirectRelayNotificationDelegate& handler, int32 channelId)
{
    // Get the network facade
    UStrixNetworkFacade* strixNetwork = UStrixNetworkFacade::GetInstance(WorldContextObject);

    // Check it exists
    if (!strixNetwork)
    {
        UE_LOG(LogStrix, Log, TEXT("StrixBlueprintFunctionLibrary::RegisterStrixRoomRelayNotificationHandler - Strix network is not initialized."));
        return;
    }

    // Call the register function
    strixNetwork->RegisterDirectRelayNotificationHandler(handler, channelId);
}
// StrixNetworkFacade.h

/** Registers a handler to call when a Relay is received
  *  @param handler The callback to call when notification received
  *  @param channelId       The channel to listen on
  */
void RegisterRelayNotificationHandler(const FStrixRoomRelayNotificationDelegate& handler, int32 channelId);

/** Registers a handler to call when a direct Relay is received
  *  @param handler The callback to call when notification received
  *  @param channelId       The channel to listen on
  */
void RegisterDirectRelayNotificationHandler(const FStrixDirectRelayNotificationDelegate& handler, int32 channelId);

Registering the Handlers

// StrixNetworkFacade.cpp

// Register Relay handler
void UStrixNetworkFacade::RegisterRelayNotificationHandler(const FStrixRoomRelayNotificationDelegate& handler, int32 channelId)
{

    // Get the room context for this channel. This represents the room connection on the client side.
    auto context = m_roomContextsByChannelId.find(channelId);
    if (context != m_roomContextsByChannelId.end())
    {

        // Get the match room client. This is what the handler will be added to.
        auto matchRoomClient = context->second->GetMatchRoomClient();
        if (matchRoomClient)
        {

            // Add the room Relay notification handler. This takes a lambda function to call when a message is received.
            // The lambda itself takes a NotificationEventArgs<RoomRelayNotificationPtr> type which contains the message.
            matchRoomClient->AddRoomRelayNotifiedHandler([=](strix::client::core::NotificationEventArgs<strix::client::room::message::RoomRelayNotificationPtr> args)
            {
                // Get the message that was sent.
                auto message = args.m_data->GetMessageToRelay();

                // In this case, the message contains an FString.
                // The conversion is undertaken by the ConvertObjectToValue<FString> templated function.
                FString messageText = strix::client::core::util::ObjectConverter::ConvertObjectToValue<FString>(message);

                // Execute the handler.
                // The handler is set in the Blueprint as a function.
                handler.ExecuteIfBound(messageText);
            });
        }
    }
}

void UStrixNetworkFacade::RegisterDirectRelayNotificationHandler(const FStrixDirectRelayNotificationDelegate& handler, int32 channelId)
{

    // Get the room context for this channel. This represents the room connection on the client side.
    auto context = m_roomContextsByChannelId.find(channelId);
    if (context != m_roomContextsByChannelId.end())
    {

        // Get the match room client. This is what the handler will be added to.
        auto matchRoomClient = context->second->GetMatchRoomClient();
        if (matchRoomClient)
        {

            // Add the room Relay notification handler. This takes a lambda function to call when a message is received.
            // The lambda itself takes a NotificationEventArgs<RoomDirectRelayNotificationPtr> type which contains the message.
            matchRoomClient->AddRoomDirectRelayNotifiedHandler([=](strix::client::core::NotificationEventArgs<strix::client::room::message::RoomDirectRelayNotificationPtr> args)
            {

                // Get the message that was sent.
                auto message = args.m_data->GetMessageToRelay();

                // In this case, the message contains an FString.
                // The conversion is undertaken by the ConvertObjectToValue<FString> templated function.
                FString messageText = strix::client::core::util::ObjectConverter::ConvertObjectToValue<FString>(message);

                // Execute the handler.
                // The handler is set in the Blueprint as a function.
                handler.ExecuteIfBound(messageText);
            });
        }
    }
}

Usage

../_images/relayhandlers.png