Integration

Heimdall will be provided as one of the following:

  • Header files and compiled static libraries

  • Source files

  • Built in with the UnrealToolkit (Unreal games only)

The following integration steps apply for the first 2 points. For Unreal games, Heimdall will already be integrated out of the box.

Heimdall Poller

HeimdallPoller is the core class in the Heimdall library that is responsible for:

  • Registering the listener with the Heimdall service.

  • Listening for incoming connection requests from senders.

  • Handling errors encountered when communicating with Heimdall service and establishing connection with a sender.

  • Deregistering the listener with the Heimdall service.

The HeimdallPoller makes use of template parameters to swap implementations in and out with ease. Follow the steps below to setup your poller.

Step 1: Define your types

Example:

#include "HeimdallPoller.hpp"
#include "HeimdallRetrier.h"

using HttpClient = Microsoft::XboxStudios::Heimdall::WinHttpHeimdall;
using Logger = Microsoft::XboxStudios::Logging::DefaultLogger<Microsoft::XboxStudios::Logging::LogSeverity::Warning>;
using Telemetry = Microsoft::XboxStudios::Heimdall::Telemetry<Logger>;
using Retrier = Microsoft::XboxStudios::Heimdall::HeimdallRetrier;
using Poller = Microsoft::XboxStudios::Heimdall::HeimdallPoller<HttpClient, Telemetry>;

Where

  • The HttpClient is the Heimdall client that HeimdallPoller will use to send request to the Heimdall service. The Heimdall library comes with the following clients:

    • WinHttpHeimdall uses WinHttp to send requests for windows platform without any authentication at the moment.

    • XblHttpClient uses XSAPI to send requests for the Xbox platform with XAL authentication.

  • The Logger is used by Telemetry to log any errors or events that occur. The DefaultLogger simply logs to the output window.

  • The Telemetry is used by the HeimdallPoller to handle any errors or events that occur. By default, the Telemetry uses the DefaultLogger to log events.

  • The Retrier is used by the HeimdallPoller to handle retry logic in the case a request fails. The Heimdall library comes with HeimdallRetrier that you can use.

  • The Poller is the core class that will start polling to the Heimdall service and listening to sender connections.

Step 2: Create your callback

Once a sender requests a connection from your listener instance, HeimdallPoller will invoke a callback method. Example:

#include "HeimdallPoller.hpp"

using namespace Microsoft::XboxStudios::Heimdall;

tl::optional<ConnectionToSenderError> ConnectToSender(const Endpoint& endPoint, const Listener& handshakeCode)
{
    cout << "A sender endpoint has been received by Heimdall successfully." << endl;
    // Establish connection here
    return tl::none<ConnectionToSenderError>();
}

Note that the handshakeCode can be used to verify the connection is valid after establishing connection to the provided endPoint.

Step 3: Configuration

There are two types of configurations required.

It is recommended to configure the above via some configuration file or command line arguments.

The following is an example on how to create a Listener:

#include "Listener.h"

auto listenerName = UserAccessibleKey::Create("a");
if (tl::IsNone(listenerName))
{
    // Failed to create listener name. Handle error accordingly.
}

auto listenerKey = UserAccessibleKey::Create("b");
if (tl::IsNone(listenerKey))
{
    // Failed to create listener key. Handle error accordingly.
}

Listener l(
    tl::GetValue(listenerName),
    tl::GetValue(listenerKey));

Step 4: Polling

Finally, create an instance of the HeimdallPoller and start polling in some init method in your application:

#include "HeimdallPoller.hpp"
#include "HeimdallRetrier.h"

// listen port is the port your application is accepting connections at.
// The default ServiceInfo configuration is used below.
// Only modify the ServiceInfo if using a unique instance of the Heimdall service.
// l is the Listener created in step 3.
Poller poller(ListenerInfo(l, listenPort), ServiceInfo());

poller.StartPoll(ConnectToSender, make_unique<Retrier>());

Call StopPoll whenever you wish to stop polling or before application exit. By default the poller will stop when it goes out of scope:

poller.StopPoll();