[BLOG] C++ Session Create/Find/Join/Destroy

Hi guys,

I’m having trouble getting both creating and finding sessions to work in C++ at the same time.
Whenever I’m doing one of that via blueprint and the other one via C++, it work’s just fine, so for example creating session via blueprint and finding via c++ works perfect, as well as creating via c++ and finding via blueprint.

This is a mystery for me, because this tells me that my c++ functions are actually working just fine.

This is what I did:

  1. Creating a UMyGameInstance and setting that as default game instance in the project settings.
  2. UMyGameInstance.h as follows:

public:
	UMyGameInstance(const FObjectInitializer& ObjectInitializer);

	// Test button click
	UFUNCTION(BlueprintCallable, Category = "C++ Functions")
	void TestButton();

	// Test button click
	UFUNCTION(BlueprintCallable, Category = "C++ Functions")
	void TestButtonHost();

	// Test button delegates
	void TestButtonDelegate1(bool bWasSuccessful);
	void TestButtonHostDelegate1(FName SessionName, bool bWasSuccessful);

	FOnFindSessionsCompleteDelegate OnFindSessionsCompleteDelegate;
	FDelegateHandle OnFindSessionsCompleteDelegateHandle;

	FOnCreateSessionCompleteDelegate OnCreateSessionCompleteDelegate;
	FDelegateHandle OnCreateSessionCompleteDelegateHandle;

	TSharedPtr<class FOnlineSessionSearch> SearchSettings;
	TSharedPtr<class FOnlineSessionSettings> HostSettings;

  1. UMyGameInstance.cpp as follows:

UMyGameInstance::UMyGameInstance(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// create Online session delegates:
	OnFindSessionsCompleteDelegate = FOnFindSessionsCompleteDelegate::CreateUObject(this, &UMyGameInstance::TestButtonDelegate1);
	OnCreateSessionCompleteDelegate = FOnCreateSessionCompleteDelegate::CreateUObject(this, &UMyGameInstance::TestButtonHostDelegate1);
}


void UMyGameInstance::TestButton()
{
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
		if (Sessions.IsValid())
		{
			SearchSettings = MakeShareable(new FOnlineSessionSearch());

			SearchSettings->bIsLanQuery = true;
			SearchSettings->MaxSearchResults = 10;

			SearchSettings->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);

			// Set search delegate:
			OnFindSessionsCompleteDelegateHandle = Sessions->AddOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegate);

			TSharedPtr<class FUniqueNetId> NetId = GetWorld()->GetFirstPlayerController()->PlayerState->UniqueId.GetUniqueNetId();

			// start searching for sessions:
			Sessions->FindSessions(*NetId, SearchSettings.ToSharedRef());
		}
	}
}

void UMyGameInstance::TestButtonHost()
{
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
		if (Sessions.IsValid())
		{
			HostSettings = MakeShareable(new FOnlineSessionSettings());

			HostSettings->NumPublicConnections = 2;
			HostSettings->bShouldAdvertise = true;
			HostSettings->bAllowJoinInProgress = true;
			HostSettings->bIsLANMatch = true;
			HostSettings->bUsesPresence = true;
			HostSettings->bAllowJoinViaPresence = true;

			// Set complete delegate:
			OnCreateSessionCompleteDelegateHandle = Sessions->AddOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegate);

			// start creating a session:
			FName SessionName = FName("Test");
			bool Status = Sessions->CreateSession(0, SessionName, *HostSettings);

			if (Status) GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("UMyGameInstance::TestButtonHost Create OK"));
		}
	}
}

void UMyGameInstance::TestButtonDelegate1(bool bWasSuccessful)
{
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("UMyGameInstance::TestButtonDelegate1"));

	IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
		if (Sessions.IsValid())
		{

			Sessions->ClearOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegateHandle);

			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Num Search Results: " + FString::FromInt(SearchSettings->SearchResults.Num())));
		}
	}
}

void UMyGameInstance::TestButtonHostDelegate1(FName SessionName, bool bWasSuccessful)
{
	if (bWasSuccessful)
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("UMyGameInstance::TestButtonHostDelegate1 Name: " + SessionName.ToString()));
	else
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("UMyGameInstance::TestButtonHostDelegate1 ERROR"));

	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
		Sessions->ClearOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegateHandle);

		//StartCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(StartCompleteDelegate);
		Sessions->StartSession(SessionName); // for testing
	}
}

  1. Added two button which just calls UMyGameInstance::TestButton() and UMyGameInstance::TestButtonHost()
  2. in my project build cs:

        // Uncomment if you are using online features
	PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // Adding Subsystem utils:
        PublicDependencyModuleNames.AddRange(new string] { "OnlineSubsystem", "OnlineSubsystemUtils" });

        // Adding Subsystem service implementation:
        DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        DynamicallyLoadedModuleNames.AddRange(new string] { "OnlineSubsystemNull" });

  1. In my DefaultEngine.ini:


[/Script/Engine.GameEngine]
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")

[OnlineSubsystem]
;DefaultPlatformService=Null
DefaultPlatformService=Steam
PollingIntervalInMs=20

[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=480
bVACEnabled=0

[/Script/OnlineSubsystemSteam.SteamNetDriver]
NetConnectionClassName="OnlineSubsystemSteam.SteamNetConnection"

[OnlineSubsystemNull]


And that’s it - Both creating and finding sessions in C++ works, but not at the same time. But when i either create a session or search for sessions via blueprint, the respective C++ counterpart works perfect.
For testing i simply use two PIE windows: one for hosting, one for joining.

eXi, can you maybe send me your project so I can check that out? Hopefully I find my problem here and can contribute to the documentation.

Greetings!