Colyseus 的内置房间

大厅房间

大厅房间 (LobbyRoom) 是多人在线游戏中常见的一种特殊的房间. 加入到大厅房间的客户端会实时收到各个游戏房间的建立/撤销之类的消息.
在 Colyseus 中, 处于房间 (Room) 中的客户端如果需要了解其他房间的情况, 必须使用 Presence. 而内置的 LobbyRoom 就为开发者提供了这类开箱即用的功能.
注意, 目前版本的 Colyseus 的大厅房间通知客户端的方式使用的是 send(message), 而以后的更新版本会把这些通知消息放到 state 中.
大厅房间自动向客户端发送三种消息:

消息 含义
“rooms” 当客户端新加入大厅房间时会收到的房间列表消息
“+” 有新建房间时客户端会收到的消息
“-” 有销毁房间时客户端会收到的消息

客户端可以根据这些消息以实时更新房间列表.

import { Client, RoomAvailable } from "colyseus.js";

const client = new Client("ws://localhost:2567");
const lobby = await client.joinOrCreate("lobby");

let allRooms: RoomAvailable[] = [];

lobby.onMessage("rooms", (rooms) => {
  allRooms = rooms;
});

lobby.onMessage("+", ([roomId, room]) => {
  const roomIndex = allRooms.findIndex((room) => room.roomId === roomId);
  if (roomIndex !== -1) {
    allRooms[roomIndex] = room;

  } else {
    allRooms.push(room);
  }
});

lobby.onMessage("-", (roomId) => {
  allRooms = allRooms.filter((room) => room.roomId !== roomId);
});

中继房间

中继房间 (RelayRoom) 是一种特殊的房间. 中继房间就像路由器一样, 它的功能就是把房间内客户端发来的信息, 传送到其他客户端中去. 中继房间在普通房间的基础上剔除了数据同步, 是一种轻服务端的互联模式. 这在某些情况下非常实用, 比如聊天室. 像p2p的围棋或者回合制战斗也可以使用这种发送消息/接收消息的模式, 但是这种情况下只能在客户端进行数据校验, 所以生产环境下并不推荐这样做.
中继房间内只保留了一个包括房间内所有客户端 (player) 的 state 以便客户端了解房间内的人员情况.

//
// 当玩家加入房间时
//
relay.state.players.onAdd = (player, sessionId) => {
  if (relay.sessionId === sessionId) {
    console.log("It's me!", player.name);

  } else {
    console.log("It's an opponent", player.name, sessionId);
  }
}

//
// 当玩家离开房间时
//
relay.state.players.onRemove = (player, sessionId) => {
  console.log("Opponent left!", player, sessionId);
}

//
// 当玩家断线/重连时
// (需配合服务端的 `allowReconnection: true` 参数)
//
relay.state.players.onChange = (player, sessionId) => {
  if (player.connected) {
    console.log("Opponent has reconnected!", player, sessionId);

  } else {
    console.log("Opponent has disconnected!", player, sessionId);
  }
}

1赞