Subscribe to real-time lobby events to receive updates when lobby or player state changes occur.
阅读时间8 分钟最后更新于 1 个月前
注意
重要提示:只有 1.0.0 及更高版本中可以使用大厅事件。
Lobby 软件包中包含 Lobby Events 系统,该系统允许您订阅实时大厅事件。每次成员可观察的玩家/大厅状态发生变化时,都会发送事件。例如,当玩家加入或离开时,玩家更新公开/成员数据时,或者厅主更新公开/成员大厅数据时。玩家或厅主更新大厅的私人属性时,不会发送事件。使用事件可能比通过 get 轮询大厅状态更有效,特别是因为它不需要任何操作,直到某些数据发生变化。当每秒 get 请求数量明显大于每秒收到的事件数量时,事件的效率更高。此外,事件的有效负载仅包含补丁,因此一般来说,事件的有效负载要比 get 返回的有效负载小得多,这是另一项优势。事件的最大缺点是它们不可靠,不能保证按顺序交付。有关更多信息,请参阅“大厅版本”。注意:事件可能不可靠,不能保证按顺序交付。在 Lobby 实例中调用
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; }}
注意
注意:在上述代码示例中,
OnLobbyChanged
、
OnKickedFromLobby
和
OnLobbyEventConnectionStateChanged
负责处理事件。
以下代码示例提供了
OnLobbyChanged
的示例处理程序,并展示了如何处理已删除的大厅实例。
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}
private void OnKickedFromLobby(){ // These events will never trigger again, so let’s remove it. this.m_LobbyEvents = null; // Refresh the UI in some way}
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. */ }}
private void OnLobbyChanged(ILobbyChanges changes){ changes.ApplyToLobby(m_Lobby); // Refresh the UI in some way}
调用
changes.ApplyToLobby
会原地更新大厅上发生变化的所有字段。当大厅的变化发生在原地时,该调用会修改传递到
ApplyToLobby
函数的大厅对象值。如果您需要检查是否已应用特定的更改,请检查
ILobbyChanges
接口上的
ChangedLobbyValue
成员。以下代码示例展示了如何检查这些值:
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}
大厅版本
如果要检查新获取的大厅相较于上次观察到的大厅是否发生了变化,大厅版本非常有用。每个大厅都公开了一个
Version
属性。版本从 1 开始,并且在每次成员可观察的玩家/大厅状态发生变化时都会递增。如果与大厅的一组新更改相关联的版本没有比上次观察到的大厅版本大 1,则表示更新接收顺序发生了混乱或发生了更新丢失。如果您收到了丢失消息,请执行 get 来检索最新版本。
GetLobby
API 可以选择性地接受大厅的版本作为参数。为了节省带宽,只有当指定的版本与当前版本不匹配时,才会返回大厅数据。以下示例展示了这种情况的一个例子:
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:}