What are "online beacons" and how do they work?

What are online beacons and how do they work?

1 Like

The idea behind beacons was to provide a lightweight way to contact a server before actually connecting “for real”.

Ideally you make a connection, send an RPC, get a response, and disconnect. You can ask things like “who is in the game” or “please make room for me, I’m about to join”. Traditionally, connecting to a server involved a full map load which can be frustrating to users if they do all that work only to be denied entry to an almost full game because someone got into the game first. Now you can make contact while still in the main menu, for example, and test multiple servers to pick the best one before joining. Or to inquire about information about a game in progress to “spectate” without being actually connected with an APlayerController and all that entails.

Gears 3 used beacons to reserve space in game. That way we could test many servers for space and travel to only one, knowing that you were definitely going to get into the game. It avoided contention when thousands of users all received the same 20-50 search results but only 10 could join per match. However, in UE3, this was TCP/IP and the protocol had to be implemented manually not using any reflection by UObject.

In UE4, we decided that our already existing network code was so robust and powerful, why reinvent the wheel? So I made the AOnlineBeacon class to leverage all the RPC and replication power of AActor.

Traditionally, actor replication and spawning has always been server initiated, meaning that you had to connect before you got a copy of an actor that the server also knew about. I wanted clients to be able to create an actor that would initiate contact with the server and fire a delegate when a connection has been made so that higher level code could make an RPC. Otherwise you’d need to make a connection with the server, wait for the server to send you an actor you could RPC with, then switch to that. Unwieldy in my opinion.

Clases of interest

AOnlineBeacon

  • the base class that clients and hosts
    derive from

AOnlineBeaconClient

  • base class that client implementations derive from
    – has its own UNetDriver that creates the connection with the server
    – has an OnConnected function that is the starting point for all game level requests to be made
    – has an OnFailure function when connection failures for any reason (before or during connection)

AOnlineBeaconHost

  • base class that hosts use to manage all beacon connections from clients
    – has its own UNetDriver listening for connections from clients
    – has a registry of AOnlineBeaconHostObjects (via RegisterHost()) that to route all traffic based on type
    – don’t typically need to derive from this class

AOnlineBeaconHostObject

  • base class for any host classes that want to handle traffic coming from an AOnlineBeaconClient
    – spawns the appropriate AOnlineBeaconClient on the server to match with the client

Examples

Check out TestBeaconClient.xxx for a very simple example. I believe QAGame project makes use of that through our UPROPERTY(Exec) function system.

void ASomeClassThatHostsBeacons::InitBeaconHost()
{
	if (Beacon)
	{
		Beacon->DestroyBeacon();
		Beacon = NULL;
	}

	// Create the hosting connection
	AOnlineBeaconHost* BeaconHost = GetWorld()->SpawnActor<AOnlineBeaconHost>(AOnlineBeaconHost::StaticClass());
	if (BeaconHost && BeaconHost->InitHost())
	{
		// Register a class to handle traffic of a specific type
		AOnlineBeaconHostObject* BeaconHostObject = GetWorld()->SpawnActor<AOnlineBeaconHostObject>(ATestBeaconHost::StaticClass());
		if (BeaconHostObject)
		{
			//BeaconHostObject->Init();
			BeaconHost->RegisterHost(BeaconHostObject);
			Beacon = BeaconHost;
		}
	}
}

void ASomeClientClassThatWantsAConnection::InitBeaconClient(FString& ServerURL)
{
	if (Beacon)
	{
		Beacon->DestroyBeacon();
		Beacon = NULL;
	}

	FURL TestURL(NULL, *ServerURL, TRAVEL_Absolute);
	Beacon = GetWorld()->SpawnActor<AOnlineBeacon>(ATestBeaconClient::StaticClass());
	if (Beacon)
	{
		Cast<ATestBeaconClient>(Beacon)->InitClient(TestURL);
	}
}

If you check the bottom of DataChannel.h there is a flow diagram for how the network connection works.

Look at NotifyControlMessage() implemented on the AOnlineBeaconClient and AOnlineBeaconHost classes to see how the handshaking works.

Once connected in this fashion, actors behave as they normally would under Unreal Network replication. Both client/server RPCs are available. Server to client replication only.

3 Likes

You said Server to client replication only but in the ATestBeaconClient it does Client to server and server to client RPCs. Was this a feature added or is it unstable?

Additionally you said Unreal Network replication happens as usual after the connection but can you only use RPCs? No replicated lifetime properties?

Where is the TestBeaconClient.xxx example that you mentioned above?
Also, why are there so many scarce topics in UE4? I mean, I can’t really find any resources about a lot of subjects for this engine; I’m an active C++ programmer. I haven’t spent as much time as I should in this engine, but have worked in it quite a bit. If you could point to any tutorials on how to use OnlinBeacons, that would be awesome. Yours is good, but barely scratches the surface.

Hey, just so you know, the TestBeacon classes such as the Host and Client are inside Engine\Plugins\Online\OnlineSubsystemUtils\Source\OnlineSubsystemUtils. I’d recommend downloading from their github a copy of their source so you’d be able to look through the engine easily. I’m also starting to use OnlineBeacons and would appreciate some sort of tutorial. I’d also be happy to figure out with you how to use the system.

Hopefully this can help the community. If you are still struggling with implementing beacons, I have released a new plugin for UE4.27, 5.0, 5.1 where I have fully implemented lobby beacons with a bunch of advanced features for party management and even session matchmaking. Check it out here: Advanced Lobby System in Code Plugins - UE Marketplace