Matchmaking 客户端SDK接入指南
Matchmaking 客户端SDK接入指南
客户端SDK用于创建匹配请求(ticket), ticket包含一个或是多个玩家,每个玩家包含自己的attributes信息(段位信息,游戏模式信息等),成功创建一个Ticket后,需轮询GetTicket直到ticket匹配成功拿到ip,port信息,玩家即可通过ip,port连接到游戏服务端。
1.安装配置 UOS Launcher
参考 Launcher 教程,安装 Launcher 后,关联 UOS APP,开启 Matchmaking Client 服务并安装 Matchmaking Client SDK。
注意: 请务必确认在进行后续教程之前,已经成功完成了 Launcher 教程的安装步骤,否则可能导致后续接入无法顺利进行。
2.核心类&接口
public interface IMatchmakingSDK
{
/// <summary>
/// 创建一个Ticket
/// </summary>
/// <param name="configId">匹配配置Id</param>
/// <param name="players">玩家列表</param>
/// <param name="regionId">地域Id, 可通过该变量指定你想匹配到的地域,不填则随机匹配到可用地域(当前仅Multiverse房间服务支持该选项,Sync服务填此项无效)</param>
/// <param name="roomId">房间Id, 通过指定该参数可加入指定房间(前提是该房间存在且开启了Backfill)</param>
/// <exception cref="MatchmakingClientException">抛出该异常时代表用户端传参错误导致调用api失败,比如认证失败,ConfigId找不到等情况.</exception>
/// <exception cref="MatchmakingServerException">抛出该异常时代表服务端异常,可稍后重试或联系我们</exception>
/// <returns> Ticket Id</returns>
public Task<string> CreateTicketAsync(string configId, List<Player> players, string regionId = null, string roomId = null);
/// <summary>
/// 查询指定 ticket id 的详细信息
/// </summary>
/// <param name="id">Ticket id</param>
/// <exception cref="MatchmakingClientException">抛出该异常时代表用户端传参错误导致调用api失败,比如认证失败,TicketId找不到等情况.</exception>
/// <exception cref="MatchmakingServerException">抛出该异常时代表服务端异常,可稍后重试或联系我们</exception>
/// <returns>Ticket详细信息</returns>
public Task<Ticket> GetTicketAsync(string id);
/// <summary>
/// 删除指定 ticket id
/// </summary>
/// <param name="id">Ticket id</param>
/// <exception cref="MatchmakingClientException">抛出该异常时代表用户端传参错误导致调用api失败,比如认证失败,TicketId找不到等情况.</exception>
/// <exception cref="MatchmakingServerException">抛出该异常时代表服务端异常,可稍后重试或联系我们</exception>
public Task DeleteTicketAsync(string id);
}3.集成示例
初始化SDK
try
{
MatchmakingSDK.Initialize();
}
catch (AuthException e)
{
Debug.LogErrorFormat("failed to init sdk {0}", ex);
throw;
}SDK鉴权
请您在使用 当前服务的SDK 之前,先确认是否需要同步启用我们的 UOS Passport 服务。
启用 UOS Passport 服务,可实现 UOS 系统账号体系打通(即多服务共用同一套 UOS Passport 账号,无需重复授权登录),简化账号管理流程。
特别注意 : UOS Passport 服务为独立计费服务,启用后将根据其专属计费规则额外计费: UOS Passport 计费规则
- 不使用 UOS Passport。 请确保在调用 当前服务的SDK 提供的方法之前 已经完成用户授权:
using Unity.UOS.Auth;
// 用户授权 (每次初始化服务SDK 需进行用户授权)
string userId = <userId>; // 需要授权的 UserId
string userName = <userName>; // 可选, 需要授权的 UserName
await AuthTokenManager.GenerateAccessToken(userId, userName);使用 UOS Passport。 请确保 已开通 UOS Passport 服务 并在调用 当前服务的SDK 提供的方法之前 用户已经完成 Passport 用户登录:
- 方式一:使用「Passport 外部账号系统接入」进行登录
- 方式二:使用「Passport Login」进行登录
创建Ticket
string configId = "<configId>"; // configId 即你在网页上创建匹配配置Id, configId决定了该ticket使用的匹配规则
string regionId = "<regionId>"; // regionId 即你想匹配到的地域,不填则随机匹配到可用地域. (该功能当前仅支持与multiverse搭配使用时可用)
string roomId = "<roomId>"; // 填该参数代表加入指定的房间,前提是该房间存在且开启了匹配回填
Player player = new Player
{
// player 即玩家信息,单人匹配携带一个玩家,组队匹配携带多个玩家
// 每个玩家还可以携带匹配规则需要的段位信息,游戏模式,游戏地图数据信息等
// 亦可携带更多自定义数据,所有玩家数据将传到游戏服务端
id = <playerId>, // 玩家唯一id, 如使用passport, 可使用passport personaID作为playerId; 如使用ExternalLogin,需使用你自己id系统的用户唯一Id作为该playerId
attributes = new Dictionary<string, string>
{
{"mmr", "10"}
}
};
try
{
string ticketId = await MatchmakingSDK.Instance.CreateTicketAsync(configId, new List<Player>{player}, regionId, roomId);
}
catch (MatchmakingClientException e)
{
Debug.Log($"failed to create ticket, clientEx: {e.Message}");
throw;
}
catch (MatchmakingServerException e)
{
Debug.Log($"failed to create ticket, serverEx: {e.Message}");
throw;
}注意: 匹配系统将确保匹配结果不包含重复PlayerId(Ticket 结构体中的 PlayerId),因此需要你确保不同玩家该Id不能重复,否则会造成不同玩家无法匹配到一起的问题。
这一逻辑也可以防止一个玩家创建Ticket闪退后(客户端来不及执行删除Ticket逻辑),再登陆创建Ticket, 自己匹配到自己此前创建的Ticket的问题。同时这种情况下,为了让之前的已经无效的Ticket 尽早删除,防止其在匹配系统里反复参加匹配干扰正常匹配流程,可在匹配配置界面开启Ticket心跳检测功能,开启该功能后,一个Ticket在匹配阶段如果3s内没收到一个GetTicket请求,系统将自动删除该Ticket
查看Ticket
轮询GetTicket 等待ticket匹配成功 (建议轮询间隔:1s)
string ticketId = "<ticketId>"; // 使用create ticket返回的id getTicket
try
{
Ticket ticket = await MatchmakingSDK.Instance.GetTicketAsync(ticketId);
}
catch (MatchmakingClientException e)
{
Debug.Log($"failed to get ticket, clientEx: {e.Message}");
throw;
}
catch (MatchmakingServerException e)
{
Debug.Log($"failed to get ticket, serverEx: {e.Message}");
throw;
}
public class Ticket
{
// ticket id
public string id;
// ticket 所属 appId
public string appId;
// ticket 所属 configId
public string configId;
// ticket 想要匹配到的地域
public string regionId;
// 创建该ticket 时携带的玩家列表
public List<Player> players;
// ticket 创建时间
public long createdAt;
// ticket 创建者
public string createdBy;
// ticket 状态, 可能的值有("created", "error", "awaitingAssignment", "matched")
public string status;
// ticket 连接信息
public Assignment assignment;
}
public class Assignment
{
// ticket匹配到的房间ip
public string ip;
// ticket匹配到的房间端口,形如<port-name>/port
// 比如只配置了一个端口时: http/7654; 配置了多个端口时:http/7654,grpc/7865
public string gamePorts;
// ticket匹配到的房间Id
public string roomId;
// 若匹配失败,该项会显示匹配失败原因
public string msg;
}可通过查看返回的Ticket的status 字段来判断ticket 的状态, ticket 存在以下三个状态:
- created: 已创建,匹配中
- awaitingAssignment: 匹配成功,正在创建房间
- matched: 匹配成功且创建房间完成,可查看assignment字段拿到 ip 和 gamePorts, gamePorts格式: http/7654, 前面是端口名称,后面是端口号, 如你的服务监听多个端口号,则将通过逗号隔开 http/7654,grpc/7865
- error: 匹配失败,可能是匹配超时,不适配Config,或者分配服务器失败等原因,可通过assignment字段里的Msg查看匹配失败原因
删除Ticket
匹配成功之后,你可以选择主动调用DeleteTicket删除ticket, 亦可等待系统自动删除,匹配成功或是失败的ticket, 系统将保留10分钟,10分钟后将会自动删除。
string ticketId = "<ticketId>";
try
{
await MatchmakingSDK.Instance.DeleteTicketAsync(ticketId);
}
catch (MatchmakingClientException e)
{
Debug.Log($"failed to delete ticket, clientEx: {e.Message}");
throw;
}
catch (MatchmakingServerException e)
{
Debug.Log($"failed to delete ticket, serverEx: {e.Message}");
throw;
}4.异常类
// 抛出该异常时代表客户端错误,如认证失败,参数无效等情况,详细错误信息可查看 exception message
public class MatchmakingClientException : MatchmakingException
{
public MatchmakingClientException(int errorCode, string message, System.Exception innerException) :
base(errorCode, message, innerException)
{
}
}
// 抛出该异常时代表服务端异常,可稍后重试或联系我们
public class MatchmakingServerException : MatchmakingException
{
public MatchmakingServerException(int errorCode, string message, System.Exception innerException) :
base(errorCode, message, innerException)
{
}
}