ColyseusJS 轻量级多人游戏服务器开发框架 - 中文手册(中)

快速上手多人游戏服务器开发。后续会基于 Google Agones,更新相关 K8S 运维、大规模快速扩展专用游戏服务器的文章。拥抱☁️原生🤗 Cloud-Native!

系列

ColyseusJS 轻量级多人游戏服务器开发框架 - 中文手册(上)

Web-Socket Server

Server

Server 负责提供 WebSocket server 来实现服务器和客户端之间的通信。

constructor (options)

options.server

要绑定 WebSocket Server 的 HTTP server。你也可以在你的服务器上使用 express

// Colyseus + Express
import { Server } from "colyseus";
import { createServer } from "http";
import express from "express";
const port = Number(process.env.port) || 3000;

const app = express();
app.use(express.json());

const gameServer = new Server({
  server: createServer(app)
});

gameServer.listen(port);
// Colyseus (barebones)
import { Server } from "colyseus";
const port = process.env.port || 3000;

const gameServer = new Server();
gameServer.listen(port);
options.pingInterval

服务器 "ping" 客户端的毫秒数。默认值: 3000

如果客户端在 pingMaxRetries 重试后不能响应,则将强制断开连接。

options.pingMaxRetries

没有响应的最大允许 ping 数。默认值: 2

options.verifyClient

这个方法发生在 WebSocket 握手之前。如果 verifyClient 没有设置,那么握手会被自动接受。

  • info (Object)

    • origin (String) 客户端指定的 Origin header 中的值。
    • req (http.IncomingMessage) 客户端 HTTP GET 请求。
    • secure (Boolean) true,如果 req.connection.authorizedreq.connection.encrypted 被设置。
  • next (Function) 用户必须在检查 info 字段后调用该回调。此回调中的参数为:

    • result (Boolean) 是否接受握手。
    • code (Number) 当 resultfalse 时,该字段决定发送给客户端的 HTTP 错误状态码。
    • name (String) 当 resultfalse 时,该字段决定 HTTP 原因短语。
import { Server } from "colyseus";

const gameServer = new Server({
  // ...

  verifyClient: function (info, next) {
    // validate 'info'
    //
    // - next(false) will reject the websocket handshake
    // - next(true) will accept the websocket handshake
  }
});
options.presence

当通过多个进程/机器扩展 Colyseus 时,您需要提供一个状态服务器。

import { Server, RedisPresence } from "colyseus";

const gameServer = new Server({
  // ...
  presence: new RedisPresence()
});

当前可用的状态服务器是:

  • RedisPresence (在单个服务器和多个服务器上扩展)
options.gracefullyShutdown

自动注册 shutdown routine。默认为 true。如果禁用,则应在关闭进程中手动调用 gracefullyShutdown() 方法。

define (name: string, handler: Room, options?: any)

定义一个新的 room handler

Parameters:

  • name: string - room 的公共名称。当从客户端加入 room 时,您将使用这个名称。
  • handler: Room - 引用 Room handler 类。
  • options?: any - room 初始化的自定义选项。
// Define "chat" room
gameServer.define("chat", ChatRoom);

// Define "battle" room
gameServer.define("battle", BattleRoom);

// Define "battle" room with custom options
gameServer.define("battle_woods", BattleRoom, { map: "woods" });

"多次定义同一个 room handler":

  • 您可以使用不同的 options 多次定义同一个 room handler。当调用 Room#onCreate() 时,options 将包含您在 Server#define() 中指定的合并值 + 创建房间时提供的选项。

Matchmaking 过滤器: filterBy(options)

参数

  • options: string[] - 选项名称的列表

当一个房间由 create()joinOrCreate() 方法创建时,只有 filterBy() 方法定义的 options 将被存储在内部,并用于在 join()joinOrCreate() 调用中过滤出相关 rooms

示例: 允许不同的“游戏模式”。

gameServer
  .define("battle", BattleRoom)
  .filterBy(['mode']);

无论何时创建房间,mode 选项都将在内部存储。

client.joinOrCreate("battle", { mode: "duo" }).then(room => {/* ... */});

您可以在 onCreate() 和/或 onJoin() 中处理提供的选项,以在 room 实现中实现请求的功能。

class BattleRoom extends Room {
  onCreate(options) {
    if (options.mode === "duo") {
      // do something!
    }
  }
  onJoin(client, options) {
    if (options.mode === "duo") {
      // put this player into a team!
    }
  }
}

示例: 通过内置的 maxClients 进行过滤

maxClients 是一个用于 matchmaking 的内部变量,也可以用于过滤。

gameServer
  .define("battle", BattleRoom)
  .filterBy(['maxClients']);

然后客户端可以要求加入一个能够容纳一定数量玩家的房间。

client.joinOrCreate("battle", { maxClients: 10 }).then(room => {/* ... */});
client.joinOrCreate("battle", { maxClients: 20 }).then(room => {/* ... */});

Matchmaking 优先级: sortBy(options)

您还可以根据创建时加入房间的信息为加入房间赋予不同的优先级。

options 参数是一个键值对象,在左侧包含字段名称,在右侧包含排序方向。排序方向可以是以下值之一:-1"desc""descending"1"asc""ascending"

示例: 按内置的 clients 排序

clients 是为 matchmaking 而存储的内部变量,其中包含当前已连接客户端的数量。在以下示例中,连接最多客户端的房间将具有优先权。使用 -1"desc""descending" 降序排列:

gameServer
  .define("battle", BattleRoom)
  .sortBy({ clients: -1 });

要按最少数量的玩家进行排序,您可以做相反的事情。将 1"asc""ascending" 用于升序:

gameServer
  .define("battle", BattleRoom)
  .sortBy({ clients: 1 });

启用大厅的实时 room 列表

为了允许 LobbyRoom 接收来自特定房间类型的更新,您应该在启用实时列表的情况下对其进行定义:

gameServer
  .define("battle", BattleRoom)
  .enableRealtimeListing();

监听 room 实例事件

define 方法将返回已注册的 handler 实例,您可以从 room 实例范围之外监听 match-making 事件。如:

  • "create" - 当 room 被创建时
  • "dispose" - 当 room 被销毁时
  • "join" - 当客户端加入一个 room
  • "leave" - 当客户端离开一个 room
  • "lock" - 当 room 已经被锁定时
  • "unlock" - 当 room 已经被解锁时

Usage:

gameServer
  .define("chat", ChatRoom)
  .on("create", (room) => console.log("room created:", room.roomId))
  .on("dispose", (room) => console.log("room disposed:", room.roomId))
  .on("join", (room, client) => console.log(client.id, "joined", room.roomId))
  .on("leave", (room, client) => console.log(client.id, "left", room.roomId));

不鼓励通过这些事件来操纵房间的 state。而是在您的 room handler 中使用 abstract methods

simulateLatency (milliseconds: number)

这是一种便捷的方法,适用于您希望本地测试"laggy(滞后)"客户端的行为而不必将服务器部署到远程云的情况。

// Make sure to never call the `simulateLatency()` method in production.
if (process.env.NODE_ENV !== "production") {

  // simulate 200ms latency between server and client.
  gameServer.simulateLatency(200);
}

attach (options: any)

你通常不需要调用它。只有在你有非常明确的理由时才使用它。

连接或创建 WebSocket server。

  • options.server:用于绑定 WebSocket 服务器的 HTTP 服务器。
  • options.ws:现有的可重用 WebSocket 服务器。

Express

import express from "e
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值