Create and join session in c++

I tried to use c++ to create sessions, and find and join them in unreal. I took a reference to this blog.

How To Use Sessions In C++ - UE4: Guidebook (gg-labs.com)

However, if I use my c++ code to create a session, it can be created, but my c++ can’t find the session.

But the c++ code can find the session created by the blueprint.

And, the blueprint Find Session code can find both C++ created session and Blueprint created session. But it could only join the blueprint created session.
Here is the log of creating session, upper is in blueprint and lower is in c++:

Here is for search and connection log info snippet. Everything are the same except this one:
The good one:
LogOnlineSession: OSS: Join session: traveling to MY IP:7777

But the bad one is:
LogOnlineSession: OSS: Join session: traveling to MY IP:0

what could cause this error? Anyone help!

Here is my code in c++:

// Fill out your copyright notice in the Description page of Project Settings.

#include "NetCode/NetworkInstance.h"

#include "CreateSessionCallbackProxy.h"
#include "Engine.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "OnlineSessionSettings.h"


UNetworkInstance::UNetworkInstance()
{
	OnCreateSessionCompleteDelegate = FOnCreateSessionCompleteDelegate::CreateUObject(this,&UNetworkInstance::OnSessionCreateComplete);
	OnStartSessionCompleteDelegate  = FOnStartSessionCompleteDelegate::CreateUObject(this,&UNetworkInstance::OnSessionStartComplete);
	OnFindSessionsCompleteDelegate = FOnFindSessionsCompleteDelegate::CreateUObject(this, &UNetworkInstance::OnSessionFindComplete);
}

/*Create session settings and create a session with that setting*/

bool UNetworkInstance::HostSession(int MaxConnectionNum, bool bIsLan)
{
	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		/*Get the session interface so we can call "Createsession" function*/
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			SessionSettings = MakeShareable(new FOnlineSessionSettings());
			SessionSettings->bAllowInvites = true;
			SessionSettings->bIsLANMatch = bIsLan;
			SessionSettings->NumPublicConnections =MaxConnectionNum;
			SessionSettings->NumPrivateConnections = 0;
			SessionSettings->bAllowJoinInProgress = true;
			SessionSettings->bAllowJoinViaPresence = true;
			SessionSettings->bAllowJoinViaPresenceFriendsOnly = false;
			SessionSettings->bIsDedicated = false;
			SessionSettings->bUsesPresence =true;
			SessionSettings->bShouldAdvertise = true;

			/*Set start up level*/
			SessionSettings->Set(SETTING_MAPNAME,FString("FashionNext"),EOnlineDataAdvertisementType::ViaOnlineService);
			/*Bind delegate*/
			OnCreateSessionCompleteDelegateHandle = Session->AddOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegate);
			const ULocalPlayer* LocalPlayer =GetFirstGamePlayer();
			
			if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Cyan,  FString::Printf(TEXT("Net ID:%s!"),*LocalPlayer->GetPreferredUniqueNetId().ToString()));
			/*destroy previous session first if there is one*/
			Session->DestroySession(FName("FashionNext"));
			
			return Session->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(),FName("FashionNext"),*SessionSettings);
		}

		
	}
	else
	{
		if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("No OnlineSubsytem found!"));
	}
	return false;
}

/*Once create session successfully, then try to start the session*/

void UNetworkInstance::OnSessionCreateComplete(FName SessionName, bool bIsSuccessful)
{
	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			Session->ClearOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegateHandle);
		}
		if(bIsSuccessful)
		{
			if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Cyan,  FString::Printf(TEXT("Create session successfully!")));

			OnStartSessionCompleteDelegateHandle = Session->AddOnStartSessionCompleteDelegate_Handle(OnStartSessionCompleteDelegate);
			Session->StartSession(FName("FashionNext"));
			
		}else
		{
			if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Cyan,  FString::Printf(TEXT("Create session Failed!")));
		}
		
	}

}

/*Once start session successfully, open the SCAN QR level*/
void UNetworkInstance::OnSessionStartComplete(FName SessionName, bool bIsSuccessful)
{
	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			Session->ClearOnStartSessionCompleteDelegate_Handle(OnStartSessionCompleteDelegateHandle);
		}
		if(bIsSuccessful)
		{
			if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Cyan,  FString::Printf(TEXT("Start :%s session successfully!"),*SessionName.ToString()));

			UGameplayStatics::OpenLevel(GetWorld(),FName("ScanQR"),true,FString("?listen"));
		}else
		{
			if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Cyan,  FString::Printf(TEXT("Start :%s session Failed!"),*SessionName.ToString()));
		}
	}
}

/*Try to find Session*/

void UNetworkInstance::FindSession(bool bIsLAN)
{
	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			SessionSearch = MakeShareable(new FOnlineSessionSearch);
			SessionSearch->bIsLanQuery = bIsLAN;
			SessionSearch->MaxSearchResults = 10;
			SessionSearch->PingBucketSize =50;
			SessionSearch->QuerySettings.Set(SEARCH_PRESENCE,true, EOnlineComparisonOp::Equals);
		}
		//Using in Find Sessions
		const TSharedRef<FOnlineSessionSearch> SearchSessionRef = SessionSearch.ToSharedRef();

		OnFindSessionsCompleteDelegateHandle = Session->AddOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegate);

		const ULocalPlayer* LocalPlayer = GetFirstGamePlayer();
		if(GEngine)GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Cyan,  FString::Printf(TEXT("Net ID:%s!"),*LocalPlayer->GetPreferredUniqueNetId().ToString()));

		Session->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(),SearchSessionRef);
	}else
	{
		// If something goes wrong, just call the Delegate Function directly with "false".
		OnSessionFindComplete(false);
	}
}

void UNetworkInstance::SimplfiedJoined()
{
	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			SessionSearch = MakeShareable(new FOnlineSessionSearch);
			SessionSearch->bIsLanQuery = false;
			SessionSearch->MaxSearchResults = 10;
			SessionSearch->PingBucketSize =50;
			SessionSearch->QuerySettings.Set(SEARCH_PRESENCE,true, EOnlineComparisonOp::Equals);
			const TSharedRef<FOnlineSessionSearch> SearchSessionRef = SessionSearch.ToSharedRef();

			const ULocalPlayer* LocalPlayer = GetFirstGamePlayer();
			Session->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(),SearchSessionRef);
			if(SessionSearch->SearchResults.Num()>0)
			{
				if(GEngine)	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Cyan, FString::Printf(TEXT("Yeah!")));
				Session->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),FName("FashionNext"),SessionSearch->SearchResults[0]);
			}
		}
	}
}


void UNetworkInstance::OnSessionFindComplete( bool bIsSuccessful)
{
	
	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			if(GEngine)	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Cyan, FString::Printf(TEXT("Num Search Results: %d"), SessionSearch->SearchResults.Num()));

			Session->ClearOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegateHandle);
			if(SessionSearch->SearchResults.Num()>0)
			{
				const ULocalPlayer* LocalPlayer = GetFirstGamePlayer();

				for(auto& SearchResult:SessionSearch->SearchResults)
				{
					
					if(SearchResult.Session.OwningUserId != LocalPlayer->GetPreferredUniqueNetId())
					{
						Join(SearchResult);
						break;
					}
				}
			}
		}
		if(!bIsSuccessful)
		{
			if(GEngine)	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Num Search Results: %d"), SessionSearch->SearchResults.Num()));

		}
	}
	
}


bool UNetworkInstance::Join(const FOnlineSessionSearchResult& SearchResult)
{

	if(const IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get())
	{
		IOnlineSessionPtr Session = OnlineSubsystem->GetSessionInterface();
		if(Session.IsValid())
		{
			OnJoinSessionCompleteDelegateHandle = Session->AddOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegate);
			const ULocalPlayer* LocalPlayer = GetFirstGamePlayer();
			if(GEngine)	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Trying to join!")));

			return Session->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),FName("FashionNext"),SearchResult);
		}
		
	}
	return false;
}
void UNetworkInstance::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
	if(GEngine)	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnJoinSessionComplete %s, %d"), *SessionName.ToString(), static_cast<int32>(Result)));
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		// Get SessionInterface from the OnlineSubsystem
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid())
		{
			// Clear the Delegate again
			Sessions->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);

			// Get the first local PlayerController, so we can call "ClientTravel" to get to the Server Map
			// This is something the Blueprint Node "Join Session" does automatically!
			APlayerController * const PlayerController = GetFirstLocalPlayerController();

			// We need a FString to use ClientTravel and we can let the SessionInterface contruct such a
			// String for us by giving him the SessionName and an empty String. We want to do this, because
			// Every OnlineSubsystem uses different TravelURLs
			FString TravelURL;

			if (PlayerController && Sessions->GetResolvedConnectString(SessionName, TravelURL))
			{
				// Finally call the ClienTravel. If you want, you could print the TravelURL to see
				// how it really looks like
				PlayerController->ClientTravel(TravelURL, ETravelType::TRAVEL_Absolute);
			}
		}
	}
}

Update: I managed to launch it in Standalone mode and, well, at least it can find the session with c++. But still, I can not join session nor travel to the map of the server

Hello,buddy.
Check if your computer is connected to a network cable,if not,it is normal that you can not join session. this function will get your computer’s ipv4 to locate the host,you won’t get a ip address if network cable is not connected.

Did you solve this problem?

Your problem could be the one discussed here:

use Online::GetSessionInterface(GetWorld()) instead of IOnlineSubsystem::Get()->GetSessionInterface() it fixed it for me.