组队服务 SDK 接入指南
组队服务 SDK 接入指南
1. 初始化Push SDK并连接到 Push Server
参考 Push SDK 初始化指南,初始化 Push SDK并连接到 Push Server。
2.集成示例
创建队伍
try
{
string teamName = "teamName";
uint maxPlayer = 5;
// 玩家在一个命名空间下只能存在在一个队伍中,如果不传则为默认命名空间default
string teamNamespace = "namespace1";
Team res = await PushSDK.Instance.TeamService.CreateTeamAsync(teamName, maxPlayer, teamNamespace);
// 创建的队伍的唯一Id
Debug.Log(res.TeamId);
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to create team. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to create team. server ex: {0}", ex);
throw;
}
public class Team
{
/// <summary>
/// 队伍Id
/// </summary>
public string TeamId;
/// <summary>
/// 队伍命名空间
/// </summary>
public string Namespace;
/// <summary>
/// 队伍名称
/// </summary>
public string Name;
/// <summary>
/// 队长
/// </summary>
public string Owner;
/// <summary>
/// 队伍内玩家列表
/// </summary>
public List<string> Players;
/// <summary>
/// 队伍最大人数
/// </summary>
public uint MaxPlayerCount;
/// <summary>
/// 队伍创建时间
/// </summary>
public Timestamp CreatedAt;
/// <summary>
/// 队伍上次锁定时间
/// </summary>
public Timestamp LastLockedAt;
/// <summary>
/// 队伍是否被锁定
/// </summary>
public bool Locked;
/// <summary>
/// 队伍可见性
/// </summary>
public TeamVisibility visibility;
/// <summary>
/// 队伍邀请码
/// </summary>
public string TeamCode;
/// <summary>
/// 组队超时时长,单位为秒
/// </summary>
public uint Ttl;
/// <summary>
/// 队伍自定义属性
/// </summary>
public Dictionary<string, string> Properties;
}
/// <summary>
/// 队伍可见性
/// </summary>
public enum TeamVisibility
{
/// <summary>
/// 公开
/// </summary>
PUBLIC,
/// <summary>
/// 私密,PickTeams时不会获取到
/// </summary>
PRIVATE
}CreateTeamAsync 支持更多可选参数:
visibility: 队伍可见性(PUBLIC/PRIVATE)generateTeamCode: 是否生成队伍邀请码(生成后可通过TeamCode分享邀请)ttl: 组队超时时长(单位:秒)properties: 队伍自定义属性(键值对)onTeamStatusNotification: 队伍状态回调(见下文“队伍状态回调”)
示例:
void OnTeamStatus(TeamStatusNotificationMessage msg)
{
Debug.Log($"team={msg.TeamId}, player={msg.PlayerId}, action={msg.TeamStatusAction}");
}
var team = await PushSDK.Instance.TeamService.CreateTeamAsync(
name: "teamName",
maxPlayerCount: 5,
teamNamespace: "namespace1",
visibility: TeamVisibility.PUBLIC,
generateTeamCode: true,
ttl: 1800,
properties: new Dictionary<string, string> { { "mode", "rank" }, { "map", "desert" } },
onTeamStatusNotification: OnTeamStatus
);
Debug.Log($"teamId={team.TeamId}, teamCode={team.TeamCode}");加入队伍
void OnTeamStatus(TeamStatusNotificationMessage msg)
{
Debug.Log($"team={msg.TeamId}, player={msg.PlayerId}, action={msg.TeamStatusAction}");
}
try
{
// 队伍唯一Id
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
Team res = await PushSDK.Instance.TeamService.JoinTeamAsync(teamId, OnTeamStatus);
Debug.Log(res.Name);
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to join team. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to join team. server ex: {0}", ex);
throw;
}队伍状态回调
创建/加入队伍时可以传入onTeamStatusNotification回调,用于监听成员加入/离开/上线/离线、队伍锁定/解锁、队伍属性更新、队伍解散/踢人等事件。
注意:如你使用了组队服务的队伍状态回调能力,当前回调是基于 SDK 内部对 teamId 频道的订阅实现的。创建队伍或加入队伍并传入 onTeamStatusNotification 后,SDK 会自动完成这个内部频道的订阅、退订和玩家状态通知配置。
因此请不要再把 teamId 当作业务频道手动调用 MessageService.SubscribeChannels / UnsubscribeChannels,也不要向 teamId 发送自定义业务消息,否则可能干扰队伍状态回调的正常行为。若需要队伍聊天、队伍广播等业务能力,请使用独立的业务频道名称。
void OnTeamStatus(TeamStatusNotificationMessage msg)
{
switch (msg.TeamStatusAction)
{
case TeamStatusAction.PlayerJoin:
case TeamStatusAction.PlayerLeave:
case TeamStatusAction.PlayerConnected:
case TeamStatusAction.PlayerDisconnected:
Debug.Log($"member event: {msg.TeamStatusAction}, player={msg.PlayerId}");
break;
case TeamStatusAction.TeamLocked:
case TeamStatusAction.TeamUnlocked:
case TeamStatusAction.TeamPropertiesUpdated:
Debug.Log($"team event: {msg.TeamStatusAction}");
break;
case TeamStatusAction.PlayerKicked:
case TeamStatusAction.TeamDismissed:
Debug.Log($"end event: {msg.TeamStatusAction}");
break;
}
}
// 加入队伍时注册队伍状态回调
await PushSDK.Instance.TeamService.JoinTeamAsync("teamId", OnTeamStatus);获取当前组队信息
try
{
List<Team> res = await PushSDK.Instance.TeamService.GetPlayerTeamsAsync();
// 当前所在的队伍数量
Debug.Log(res.Count);
foreach (var team in res)
{
Debug.Log(team.TeamId);
Debug.Log(team.Name);
foreach (var playerId in team.Players)
{
Debug.Log(playerId);
}
}
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to get teams. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to get teams. server ex: {0}", ex);
throw;
}随机选取可加入的组队
该接口用于随机获取一批可加入的队伍(例如用于“快速加入队伍”入口)。
try
{
var teams = await PushSDK.Instance.TeamService.PickTeams("namespace1", 5);
foreach (var team in teams)
{
Debug.Log($"teamId={team.TeamId}, name={team.Name}, players={team.Players.Count}/{team.MaxPlayerCount}");
}
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to pick teams. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to pick teams. server ex: {0}", ex);
throw;
}离开队伍
try
{
// 队伍唯一Id
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
await PushSDK.Instance.TeamService.LeaveTeamAsync(teamId);
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to leave team. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to leave team. server ex: {0}", ex);
throw;
}离开所有队伍
try
{
await PushSDK.Instance.TeamService.LeaveAllTeamsAsync();
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to leave all teams. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to leave all teams. server ex: {0}", ex);
throw;
}锁定组队
try
{
// 队伍唯一Id
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
await PushSDK.Instance.TeamService.LockTeamAsync(teamId);
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to lock team. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to lock team. server ex: {0}", ex);
throw;
}解锁组队
try
{
// 队伍唯一Id
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
await PushSDK.Instance.TeamService.UnlockTeamAsync(teamId);
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to unlock team. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to unlock team. server ex: {0}", ex);
throw;
}更新队伍自定义属性
try
{
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var properties = new Dictionary<string, string>()
{
{ "mode", "rank" },
{ "map", "desert" },
};
var team = await PushSDK.Instance.TeamService.UpdateTeamPropertiesAsync(teamId, properties);
Debug.Log($"updated properties count={team.Properties?.Count}");
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to update team properties. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to update team properties. server ex: {0}", ex);
throw;
}解散组队,只有owner有权限解散组队
// 只有owner有权限解散组队
try
{
// 队伍唯一Id
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
await PushSDK.Instance.TeamService.DismissTeamAsync(teamId);
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to dismiss team. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to dismiss team. server ex: {0}", ex);
throw;
}获取组过队的队友列表
try
{
// 队伍唯一Id
List<Teammate> res = await PushSDK.Instance.TeamService.ListHistoricalTeammatesAsync();
Debug.Log(res.Count);
foreach (var teammate in res)
{
Debug.Log(teammate.PlayerId);
Debug.Log(teammate.Status);
}
}
catch(PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to list historical teammates. client ex: {0}", ex);
throw;
}
catch(PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to list historical teammates. server ex: {0}", ex);
throw;
}
public class Teammate
{
/// <summary>
/// 玩家Id
/// </summary>
public string PlayerId;
/// <summary>
/// 上次组队时间
/// </summary>
public Timestamp LastCollabTime;
/// <summary>
/// 玩家状态
/// </summary>
public PlayerStatus Status;
}踢出队伍内玩家
// 只有队伍owner有权限踢出队内玩家
try
{
// 队伍唯一Id
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
// 需要踢出的玩家Id
var playerId = "xxxxxxxxx";
await PushSDK.Instance.TeamService.KickPlayer(teamId, playerId);
}
catch (PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to kick player. client ex: {0}", ex);
throw;
}
catch (PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to kick player. server ex: {0}", ex);
throw;
}根据邀请码获取队伍信息
try
{
// 队伍邀请码
var teamCode = "xxxxxx";
var team = await PushSDK.Instance.TeamService.GetTeamByCode(teamCode);
// 可以通过获取到的team信息中的Id去调用JoinTeam,加入朋友的队伍
Debug.Log(team.TeamId);
}
catch (PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to get team by code. client ex: {0}", ex);
throw;
}
catch (PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to get team by code. server ex: {0}", ex);
throw;
}根据队伍Id获取队伍信息
try
{
var teamId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var team = await PushSDK.Instance.TeamService.GetTeamById(teamId);
Debug.Log(team.Name);
Debug.Log(team.Owner);
}
catch (PushSDKClientException ex)
{
Debug.LogErrorFormat("Failed to get team by id. client ex: {0}", ex);
throw;
}
catch (PushSDKServerException ex)
{
Debug.LogErrorFormat("Failed to get team by id. server ex: {0}", ex);
throw;
}4. 附录
基础服务核心类&接口
/// <summary>
/// 创建队伍
/// </summary>
/// <param name="name">队伍名称</param>
/// <param name="maxPlayerCount">队伍人数限制</param>
/// <param name="teamNamespace">命名空间,选填,不填默认为default</param>
/// <param name="visibility">队伍可见性,默认为PUBLIC</param>
/// <param name="generateTeamCode">是否生成队伍邀请码</param>
/// <param name="ttl">组队超时时长,单位为秒</param>
/// <param name="properties">自定义属性</param>
/// <param name="onTeamStatusNotification">队伍玩家状态通知回调</param>
/// <returns>队伍信息</returns>
public Task<Team> CreateTeamAsync(string name, uint maxPlayerCount, string teamNamespace = null, TeamVisibility? visibility = null, bool? generateTeamCode = null, uint? ttl = null, Dictionary<string, string> properties = null, Action<TeamStatusNotificationMessage> onTeamStatusNotification = null);
/// <summary>
/// 获取当前组队信息
/// </summary>
/// <param name="teamNamespace">命名空间,选填,⽤于指定获取玩家在某个特定命名空间下的组队信息,不填则获取所有</param>
/// <returns>队伍列表</returns>
public Task<List<Team>> GetPlayerTeamsAsync(string teamNamespace = null);
/// <summary>
/// 加入队伍
/// </summary>
/// <param name="teamId">队伍Id</param>
/// <param name="onTeamStatusNotification">队伍玩家状态通知回调</param>
/// <returns>队伍信息</returns>
public Task<Team> JoinTeamAsync(string teamId, Action<TeamStatusNotificationMessage> onTeamStatusNotification = null);
/// <summary>
/// 离开队伍
/// </summary>
/// <param name="teamId">队伍Id</param>
public Task LeaveTeamAsync(string teamId);
/// <summary>
/// 离开所有队伍
/// </summary>
/// <param name="namespaceList">命名空间,选填</param>
public Task LeaveAllTeamsAsync(List<string> namespaceList = null);
/// <summary>
/// 锁定组队
/// </summary>
/// <param name="teamId">队伍Id</param>
public Task LockTeamAsync(string teamId);
/// <summary>
/// 解锁组队
/// </summary>
/// <param name="teamId">队伍Id</param>
public Task UnlockTeamAsync(string teamId);
/// <summary>
/// 解散组队,只有owner有权限解散组队
/// </summary>
/// <param name="teamId">队伍Id</param>
public Task DismissTeamAsync(string teamId);
/// <summary>
/// 获取组过队的队友列表
/// </summary>
/// <param name="count">数量</param>
/// <param name="filterOfflinePlayers">是否只返回在线的玩家</param>
/// <returns>组过队的队友列表</returns>
public Task<List<Teammate>> ListHistoricalTeammatesAsync(uint? count = null, bool? filterOfflinePlayers = null);
/// <summary>
/// 随机选取可加入的组队
/// </summary>
/// <param name="teamNamespace">命名空间,选填,默认default</param>
/// <param name="count">数量,选填,默认5个</param>
public Task<List<Team>> PickTeams(string teamNamespace = null, uint? count = null);
/// <summary>
/// 踢出队伍内玩家,只有owner有权限
/// </summary>
/// <param name="teamId">队伍Id</param>
/// <param name="kickedPlayerId">需要踢出的玩家Id</param>
/// <returns></returns>
public Task KickPlayer(string teamId, string kickedPlayerId);
/// <summary>
/// 根据邀请码获取队伍信息
/// </summary>
/// <param name="teamCode">队伍邀请码</param>
/// <returns></returns>
public Task<Team> GetTeamByCode(string teamCode);
/// <summary>
/// 根据队伍Id获取队伍信息
/// </summary>
/// <param name="teamId">队伍Id</param>
/// <returns>队伍信息</returns>
public Task<Team> GetTeamById(string teamId);
/// <summary>
/// 更新队伍自定义属性
/// </summary>
/// <param name="teamId">队伍Id</param>
/// <param name="properties">自定义属性</param>
/// <returns>队伍信息</returns>
public Task<Team> UpdateTeamPropertiesAsync(string teamId, Dictionary<string, string> properties);