Lobby events

Important: Lobby events are only available in version 1.0.0 and later.

The Lobby package includes the Lobby Events system, which allows you to subscribe to real-time lobby events. Events are sent every time member-observable player/lobby state is changed. For example, when a player joins or leaves, a player updates public/member data, or the host updates public/member lobby data. Events are not sent if a player or the host updates a private property of the lobby.

Using events can be more efficient than polling for lobby state through gets, especially since it requires no action until some data is changed. Events are efficient when the number of gets per second is significantly larger than the number of events received per second. Furthermore, event payloads only contain patches, so in general, they have the additional benefit that their payloads are much smaller than those returned by a get. The biggest downside to events is that they are unreliable and do not guarantee in-order delivery. See Lobby versions for more.

Note: Events can be unreliable and do not guarantee in-order delivery.

Call the SubscribeToLobbyEventsAsync method on a Lobby instance to subscribe to receiving updates for that instance. Once subscribed, the Lobby service invokes the LobbyChanged event each time a change occurs. You can also use the ApplyToLobby helper method to apply the changes to the Models.Lobby object.

Receive updates

To subscribe to a lobby’s real-time updates, you must call:

Lobbies.Instance.SubscribeToLobbyEventsAsync(lobbyId, callbacks);
  • The callbacks object provides the callbacks for consuming the real-time changes.
  • The callbacks parameter accepts an instance of LobbyEventsCallbacks, which you must create and subscribe to.

Note: A player can only receive events for a lobby if they are in that lobby.

The following code sample demonstrates how to create a lobby and subscribe to it:

m_Lobby = await Lobbies.Instance.CreateLobbyAsync(lobbyName, maxPlayers, options);
var callbacks = new LobbyEventCallbacks();
callbacks.LobbyChanged += OnLobbyChanged;
callbacks.KickedFromLobby += OnKickedFromLobby;
callbacks.LobbyEventConnectionStateChanged += OnLobbyEventConnectionStateChanged;
try {
    m_LobbyEvents = await Lobbies.Instance.SubscribeToLobbyEventsAsync(m_Lobby.Id, callbacks);
}
catch (LobbyServiceException ex)
{
    switch (ex.Reason) {
        case LobbyExceptionReason.AlreadySubscribedToLobby: Debug.LogWarning($"Already subscribed to lobby[{m_Lobby.Id}]. We did not need to try and subscribe again. Exception Message: {ex.Message}"); break;
        case LobbyExceptionReason.SubscriptionToLobbyLostWhileBusy: Debug.LogError($"Subscription to lobby events was lost while it was busy trying to subscribe. Exception Message: {ex.Message}"); throw;
        case LobbyExceptionReason.LobbyEventServiceConnectionError: Debug.LogError($"Failed to connect to lobby events. Exception Message: {ex.Message}"); throw;
        default: throw;
    }
}

Note: In the preceding code sample, OnLobbyChanged, OnKickedFromLobby and OnLobbyEventConnectionStateChanged handle the events.

The following code sample provides an example handler for OnLobbyChanged. It demonstrates how to handle a deleted lobby instance.

private void OnLobbyChanged(ILobbyChanges changes)
{
    if (changes.LobbyDeleted)
    {
        // Handle lobby being deleted
        // Calling changes.ApplyToLobby will log a warning and do nothing
    }
    else
    {
        changes.ApplyToLobby(m_Lobby);
    }
    // Refresh the UI in some way
}

KickedFromLobby

The Lobby Event service uses the KickedFromLobby handler to remove a user from the lobby. This can happen for a number of reasons. For example, when the connection fails or if the host removes the user from the lobby. When a user gets kicked out of a lobby, they receive a message that the lobby event connection state has changed ( LobbyEventConnectionStateChanged) to unsubscribed.

The following code sample provides an example handler for OnKickedFromLobby:

private void OnKickedFromLobby()
{


    // These events will never trigger again, so let’s remove it.
    this.m_LobbyEvents = null;
    // Refresh the UI in some way
}

The following code sample provides an example handler for OnLobbyEventConnectionStateChanged:

Note: When there’s an error with the connection to Lobby Events, Lobby will not attempt to reconnect.

private void OnLobbyEventConnectionStateChanged(LobbyEventConnectionState state)
{
    switch (state)
    {
        case LobbyEventConnectionState.Unsubscribed: /* Update the UI if necessary, as the subscription has been stopped. */ break;
        case LobbyEventConnectionState.Subscribing: /* Update the UI if necessary, while waiting to be subscribed. */ break;
        case LobbyEventConnectionState.Subscribed: /* Update the UI if necessary, to show subscription is working. */ break;
        case LobbyEventConnectionState.Unsynced: /* Update the UI to show connection problems. Lobby will attempt to reconnect automatically. */ break;
        case LobbyEventConnectionState.Error: /* Update the UI to show the connection has errored. Lobby will not attempt to reconnect as something has gone wrong. */
    }
}

Apply changes to a lobby

When you subscribe to the LobbyEventCallbacks.LobbyChanged event, you receive a set of changes each time the lobby updates. It’s possible for a lobby to have a large number of changes at any given time, so the Lobby package includes a helper function to apply these changes to a lobby.

The following code snippet shows how to use the ApplyToLobby helper function to apply lobby changes:

private void OnLobbyChanged(ILobbyChanges changes)
{
    changes.ApplyToLobby(m_Lobby);
    // Refresh the UI in some way
}

Calling changes.ApplyToLobby updates all fields that have changed on a lobby in-place. When changes occur to a lobby in-place, the call modifies the values of the lobby object that were passed into the ApplyToLobby function. If you need to check whether a specific change was applied, check the ChangedLobbyValue members on the ILobbyChanges interface.

The following code sample demonstrates how to check these values:

private void OnLobbyChanged(ILobbyChanges changes)
{
    changes.ApplyToLobby(m_Lobby);
    if (changes.Name.Changed)
    {
        // Do something specific due to this change
    }
    // Refresh the UI in some way
}

Lobby versions

Lobby versions are useful for checking if a newly fetched lobby has changed since the last observed lobby. Every lobby exposes a Version property. Versions start at 1 and are incremented every time member-observable player/lobby state is changed.

If the version associated with a new set of lobby changes is not exactly one greater than the last observed lobby version, an update has been received out of order or lost. If you have a missing message, perform a get to retrieve the latest version.

The GetLobby API can optionally accept the version of the lobby as an argument. To save bandwidth, a lobby is only returned if the specified version doesn’t match the current version.

The following sample shows an example of this:

var lobby = await Lobbies.Instance.GetLobbyAsync("lobbyId");
var version = lobby.Version;

// check if a newer version of the lobby is available:
var newLobby = await Lobbies.Instance.GetLobbyAsync("lobbyId", version);
if (newLobby != null)
{
    // New lobby version received
    version = lobby.Version;
    // observe changed values in newLobby:

}

Troubleshooting

Make sure you handle all of the events provided, particularly OnLobbyEventConnectionStateChanged and OnKickedFromLobby as these may indicate that the Lobby Events have stopped.

OnLobbyEventConnectionStateChanged

The connection status for the Lobby Events indicates whether or not you will be receiving events.

The following are the connection statuses:

Unsubscribed

  • You have chosen to unsubscribe using ILobbyEvents.UnsubscribeAsync
  • You will not receive lobby events anymore.

Subscribing

  • The Lobby Events is trying to connect.
  • You will not receive lobby events.

Subscribed

  • The Lobby Events connects successfully.
  • You will receive lobby events.

Unsynced

  • There is a temporary problem with the connection.
  • Lobby Events will automatically try to reconnect.
  • You will not receive lobby events.

Error

  • There is an unrecoverable problem with the connection.
  • This might indicate a larger issue, such as an internet outage. A solution will require manual intervention and you might have to subscribe again.
  • You will not receive lobby events.

API

Interfaces

ILobbyServiceSDK

Method / Property NameReturn TypeDescription
SubscribeToLobbyEventsAsyncTask<ILobbyEvents>Subscribes to lobby events and returns an object to control that subscription.

ILobbyEvents

Method / Property NameReturn TypeDescription
CallbacksLobbyEventCallbacksGets the callbacks object you provided when you call SubscribeToLobbyAsync.
SubscribeAsyncTaskSubscribes to events. This is done automatically when you first call SubscribetoLobbyAsync, but if you unsubscribe, you can subscribe again later.
UnsubscribeAsyncTaskUnsubscribes from the lobby events, so that you will stop receiving changes.

ILobbyChanges

Method / Property NameReturn TypeDescription
LobbyDeletedboolA boolean value indicating whether the lobby was deleted. It’s true if the lobby was deleted and false if it is still available.
NameChangedLobbyValue<string>The change to the lobby’s name, if it has changed.
IsPrivateChangedLobbyValue<bool>The change for if the lobby is private, if it has changed.
IsLockedChangedLobbyValue<bool>The change for if the lobby is locked, if it has changed.
AvailableSlotsChangedLobbyValue<int>The change to the available slots in the lobby, if it has changed.
MaxPlayersChangedLobbyValue<int>The change to the maximum number of players in the lobby, if it has changed.
DataChangedOrRemovedLobbyValue<Dictionary<string, ChangedOrRemovedLobbyValue<DataObject>>>The changes to the lobby’s data, if it has changed.
PlayerLeftChangedLobbyValue<List<int>>A list of players that have left, if any.
PlayerJoinedChangedLobbyValue<List<LobbyPlayerJoined>>A list of players that have joined, if any.
PlayerDataChangedLobbyValue<Dictionary<int, LobbyPlayerUpdated>>The changes to player’s data, if any have changed.
HostIdChangedLobbyValue<string>The change to the lobby’s host ID, if it has changed.
VersionintThe latest version of the lobby.
LastUpdatedChangedLobbyValue<DateTime>The time the lobby changes occurred.
ApplyToLobbyvoidTakes a lobby and a change applicator to update a given lobby in-place.

Classes, Structs and Enums

LobbyEventCallbacks

Event NameArguments TypeDescription
LobbyChangedILobbyChangesWhen a lobby changes on the server, the Lobby service raises this event with a set of the changes that occurred.
KickedFromLobby When the subscription to the lobby on the server has been kicked.
LobbyEventConnectionStateChangedLobbyEventConnectionStateWhen the subscription connection changes state.

ChangedLobbyValue<T>

Property NameReturn TypeDescription
ValueTThe new value provided by the change.
ChangedboolTrue if a change has occurred, false if there has been no change.

LobbyValueChangeType<T>

Enum Value NameEnum ValueDescription
Unchanged0The value was unchanged.
Changed1The value changed.
Removed2The value was removed.

ChangedOrRemovedLobbyValue<T>

Property NameReturn TypeDescription
ValueTThe new value provided by the change.
ChangedboolTrue if a change has occurred, false if there has been no change.
ChangeTypeLobbyValueChangeTypeWhether this is a change or a removal.

Error Codes

The following error codes have been added:

LobbyExceptionReason Enum ValueError CodeDescription
AlreadySubscribedToLobby16601You are already subscribed to this lobby and have attempted to subscribe to it again
SubscriptionToLobbyLostWhileBusy16602The connection was lost or dropped while attempting to do something with the connection such as subscribe or unsubscribe
LobbyEventServiceConnectionError16603Something went wrong when trying to connect to the lobby service. Ensure a valid Lobby ID was sent