多人在线对战功能介绍
多人在线对战是 TDS 专门针对多人在线类型的游戏推出的后端服务。开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配、在线对战消息同步等功能。
核心功能
- 玩家匹配:随机或按指定条件将玩家匹配到一起玩游戏。在线对战的匹配功能会将即将一起游戏的玩家匹配到同一个房间(Room)中。例如《第五人格》、《王者荣耀》、《吃鸡》等对战类手游,玩家只需点击「自由匹配」就可以迅速匹配到其他玩家,大家进入到同一个房间中准备开始游戏;玩家也可以自己新开房间邀请好友一起玩。
- 对战消息快速同步:客户端与服务端使用 WebSocket 通道进行实时双向通信,确 保游戏内所有消息能够快速同步。
- 游戏逻辑运算:在线对战提供了 MasterClient 作为客户端主机控制游戏逻辑。游戏内的所有逻辑都交给 MasterClient 来判断运转,如果 MasterClient 意外掉线,我们会自动将网络状态最好的客户端切换为 MasterClient,确保游戏顺畅进行;开发者也可以选择在服务端编写游戏逻辑(服务端游戏逻辑支持尚在开发中)。
- 多平台支持:完美适配游戏引擎 Unity 及 Cocos Creator,支持多个平台。
特性
- 支持动态扩容,从容应对海量并发。
- 在久经考验的底层架构上进行了深度优化与改进,可以稳定承接每秒亿级的消息下发量。
核心概念
Client 和 UserId
多人在线对战服务中的每一个终端称为一个「Client」,每一个 Client 在整个对战服务中都有一个唯一标识 UserId,这个 UserId 只允许英文、数字与下划线,长度不能超过 32 个字符,在一个应用内全局唯一。每一个游戏玩家都肯定是一个 Client,但并不是所有的 Client 都是真正的玩家,例如托管在 Client Engine 中管理房间的 MasterClient 或自己写的 AI 玩家。
多人在线对战服务仅允许一个 Client 同时和服务器建立一条连接,如果已登录 UserId 再次尝试登录,第二次登录会把之前的登录踢掉。
房间和 ActorId
当玩家匹配成功后,会进入到同一个房间内进行游戏,对战的消息会在这个房间内快速同步。每一个玩家在该房间内有一个自己的专属 ActorId,房间内的通信全部通过 ActorId 来传递。玩家退出房间后,ActorId 失效,当玩家进入下一个房间后,会获得新的房间内的 ActorId。
一个房间最多支持 10 人同时在线。
游戏核心流程
这里给出简单的示例代码使您更快地了解到整体流程,详细的开发指南请参考:
连接服务器
- JavaScript
- C#
const client = new Client({
appId: 'your-client-id', // 游戏的 Client ID
appKey: 'your-client-token', // 游戏的 Client Token
playServer: 'https://your_server_url', // 游戏的 API 域名
userId: 'tarara', // 设置用户 id
gameVersion: '0.0.1' // 设置游戏版本号,选填,默认 0.0.1,不同版本的玩家不会匹配到同一个房间
});
client.connect().then(()=> {
// 连接成功
}).catch(console.error);
- 在 开发者中心 > 你的游戏 > 游戏服务 > 应用配置 可以查看游戏的
Client ID和Client Token。 - API 域名在 应用配置 > 域名配置 > API 处查看,参考文档关于域名的说明。
Play.UserID = "tarara";
// 连接服务器时可以声明游戏版本,不同版本的玩家不会匹配到同一个房间
Play.Connect("0.0.1");
玩家匹配
随机匹配
单人玩游戏时,最常见的场景是随机匹配其他玩家迅速开始。具体实现步骤如下:
1、调用 JoinRandomRoom 开始匹配。
- JavaScript
- C#
client
.joinRandomRoom()
.then(() => {
// 成功加入房间
})
.catch(console.error);
Play.JoinRandomRoom();
2、在顺利情况下,会进入某个有空位的房间开始游戏。
- JavaScript
- C#
// JavaScript SDK 通过 joinRandomRoom 的 Promise 判断是否加入房间成功
play.On(Event.ROOM_JOINED, (evtData) => {
// 成功加入房间
});
3、如果没有空房间,就会加入失败。此时在失败触发的回调中建立一个房间等待其他人加入,建立房间时:
- 不需要关心房间名称。
- 默认一个房间内最大人数是 10,可以通过设置 MaxPlayerCount 来限制最大人数。
- 设置 玩家掉线后的保留时间,在有效时间内如果该玩家加回房间,房间内依然保留该玩家的自定义属性。
- JavaScript
- C#
client
.joinRandomRoom()
.then()
.catch((error) => {
if (error.code === 4301) {
const options = {
// 设置最大人数,当房间满员时,服务端不会再匹配新的玩家进来。
maxPlayerCount: 4,
// 设置玩家掉线后的保留时间为 120 秒
playerTtl: 120,
};
// 创建房间
client
.createRoom({
roomOptions: options,
})
.then(() => {
// 创建房间成功
});
}
});
// 加入失败时,这个回调会被触发
play.On(Event.ROOM_JOIN_FAILED, (evtData) =>
{
var options = new RoomOptions()
{
// 设置最大人数,当房间满员时,服务端不会再匹配新的玩家进来。
MaxPlayerCount = 4,
// 设置玩家掉线后的保留时间为 120 秒
PlayerTtl = 120,
};
play.CreateRoom(roomOptions: options);
});
自定义房间匹配规则
有的时候我们希望将水平差不多的玩家匹配到一起。例如当前玩家 5 级,他只能和 0-10 级的玩家匹配,10 以上的玩家无法被匹配到。这个场景可以通过给房间设置属性来实现,具体实现逻辑如下:
1、确定匹配属性,例如 0-10 级是 level-1,10 以上是 level-2。
- JavaScript
- C#
var matchLevel = 0;
if (level < 10) {
matchLevel = 1;
} else {
matchLevel = 2;
}
int matchLevel = 0;
if (level < 10) {
matchLevel = 1;
} else {
matchLevel = 2;
}
2、根据匹配属性加入房间
- JavaScript
- C#
const matchProps = {
level: matchLevel,
};
client
.joinRandomRoom({ matchProperties: matchProps })
.then(() => {
// 成功加入房间
})
.catch(console.error);
Hashtable matchProp = new Hashtable();
matchProp.Add("matchLevel", matchLevel);
Play.JoinRandomRoom(matchProp);
3、如果随机加入房间失败,则创建具有匹配属性的房间等待其他同水平的人加入。
- JavaScript
- C#
const matchProps = {
level: matchLevel,
};
client
.joinRandomRoom({ matchProperties: matchProps })
.then()
.catch((error) => {
if (error.code === 4301) {
const options = {
// 设置最大人数,当房间满员时,服务端不会再匹配新的玩家进来。
maxPlayerCount: 4,
// 设置玩家掉线后的保留时间为 120 秒
playerTtl: 120,
// 房间的自定义属性
customRoomProperties: matchProps,
// 从房间的自定义属性中选择匹配用的 key
customRoomPropertyKeysForLobby: ["level"],
};
client
.createRoom({
roomOptions: options,
})
.then()
.catch(console.error);
}
});
play.On(Event.ROOM_JOIN_FAILED, (error) => {
if (error["code"] == 4301)
{
var props = new Dictionary<string, object>();
props.Add("level", 2);
var options = new RoomOptions()
{
// 设置最大人数,当房间满员时,服务端不会再匹配新的玩家进来。
MaxPlayerCount = 3,
// 设置玩家掉线后的保留时间为 120 秒
PlayerTtl = 120,
// 房间的自定义属性
CustomRoomProperties = props,
// 从房间的自定义属性中选择匹配用的 key
CustoRoomPropertyKeysForLobby = new List<string>() { "level" },
};
play.CreateRoom(roomOptions: options);
}
});
和好友一起玩
假设 PlayerA 希望能和好基友 PlayerB 一起玩游戏,这时又分以下两种情况:
- 只是两个人一起玩,不允许陌生人加入
- 好友和陌生人一起玩