ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

boardgame.io Server 服务端完整指南:配置、运行、自定义认证与扩展

boardgame.io Server 服务端完整指南:配置、运行、自定义认证与扩展 游戏开发【免费下载链接】boardgame.ioState Management and Multiplayer Networking for Turn-Based Games项目地址https://gitcode.com/gh_mirrors/bo/boardgame.io点击查看免费下载导读Server是 boardgame.io 的官方服务端入口负责为启用了multiplayer: true的客户端提供实时联机能力它在 Koa 之上维护各个对局的权威状态并通过 socket.io 把状态更新广播给同一房间内的所有浏览器同时托管一套用于创建/加入对局的 REST Lobby API。读完本文你将掌握Server()的全部配置参数、四种典型启动方式基础、回调、独立 Lobby 端口、HTTPS、自定义玩家凭证认证的完整实现以及如何通过 Koa Router 为服务端扩展自定义路由与中间件。文中所有结论均与 Server.md 文档及本仓库源码src/server/目录相互印证。一、Server 是什么服务端架构与职责按 Server.md 的定义Server创建一个 boardgame.io 服务端它仅在客户端设置multiplayer: true时才需要。它创建了一个 Koa 应用完成三件事跟踪状态维护连接到它的各客户端的游戏状态权威状态由Master类持有见 src/master/master.ts实时广播将更新推送给所有客户端使连接到同一对局的所有浏览器实时保持同步托管 REST API提供用于创建和加入对局的 Lobby API默认与游戏服务共用同一端口也可配置为独立端口运行。从源码看Server工厂函数定义在 src/server/index.ts它会依次完成创建 Koa 应用new Koa()→ 通过ProcessGameConfig规范化游戏定义 → 选择数据库未提供时用DBFromEnv()自动选择→ 构造Auth实例 → 选择传输层默认SocketIO→ 初始化路由。最终通过packages/server.tspackages/server.ts对外导出Server、Origins、FlatFile、SocketIO、GenericPubSub。注意自 boardgame.io0.45 起CORS 默认不再开启。若未设置originsServer会在控制台打印警告见 src/server/index.ts必须显式声明允许连接的来源。二、构造参数全解Server({ ... })接收一个配置对象以下是全部选项参数类型必填说明gamesarray✅游戏实现列表每个元素为符合 Game API 的对象originsarray✅允许访问游戏服务器的 CORS 来源列表可含字符串或正则表达式dbobject—数据库连接器不传则使用内存实现transportobject—传输层实现不传则使用 socket.iouuidfunction—返回唯一标识的函数用于生成游戏 ID 与玩家凭证默认使用 nanoidgenerateCredentialsfunction—生成玩家凭证存入游戏元数据的函数未指定时使用uuidauthenticateCredentialsfunction—校验玩家行动凭证的函数用于默认 socket.io 传输层apiOriginsarray—Lobby API 的允许来源默认取origins的值2.1 games游戏定义列表games是服务端的核心输入。源码中每个游戏都会先经过ProcessGameConfig(game)规范化src/server/index.ts然后被注册为 socket.io 的独立命名空间app._io.of(game.name)src/server/transport/socketio.ts每个游戏拥有独立的实时通信频道被注册进 Lobby 路由用于GET /games列出游戏名、POST /games/:name/create创建对局等操作src/server/api.ts。2.2 origins 与 apiOriginsCORS 白名单origins是必填的 CORS 白名单元素可以是字符串精确匹配请求的 Origin 头或正则表达式模式匹配实现位于 src/server/cors.tsconst LOCALHOST /localhost:\d/; export const Origins { LOCALHOST, LOCALHOST_IN_DEVELOPMENT: process.env.NODE_ENV production ? false : LOCALHOST, };Origins.LOCALHOST_IN_DEVELOPMENT是一个便捷常量开发环境NODE_ENV不为production下放行任意localhost端口的页面连接生产环境下则为false拒绝。这是文档推荐的本机联调写法。apiOrigins默认回退到origins源码中apiOrigins origins见 src/server/index.ts用于独立限制 Lobby API 的跨域访问。匹配逻辑支持数组递归、字符串、正则、布尔四种形态实现在isOriginAllowed见 src/server/api.ts。2.3 db存储连接器db是 boardgame.io 的存储抽象项目是存储无关的详见 storage.md。若未提供Server内部调用DBFromEnv()src/server/db/index.tsconst DBFromEnv () { return process.env.FLATFILE_DIR ? new FlatFile({ dir: process.env.FLATFILE_DIR }) : new InMemory(); };即设置了FLATFILE_DIR环境变量则使用磁盘平铺文件存储FlatFile否则使用InMemory内存存储重启即丢失。内置连接器包括InMemorysrc/server/db/inmemory.ts与FlatFilesrc/server/db/flatfile.ts均实现StorageAPI接口src/server/db/base.ts。文档还提到 Firebase、Azure Storage、Postgres 等第三方后端以及用于减轻数据库压力的缓存方案boardgame.io/storage-cache。2.4 transport传输层transport默认是 socket.io 实现new SocketIO({ https })见 src/server/index.ts。SocketIO类src/server/transport/socketio.ts还支持传入socketAdapter如多实例部署时的 Redis 适配器、socketOpts透传 socket.io 服务端选项与pubSub默认InMemoryPubSub。其内部配置了PING_TIMEOUT 20s、PING_INTERVAL 10s的心跳参数并为每个对局维护一个PQueue并发度为 1保证同一对局内的行动串行处理避免状态竞争src/server/transport/socketio.ts。2.5 uuid 与凭证相关函数uuid生成游戏 ID 与玩家凭证的函数默认nanoid源码中 Lobby 路由的默认值即() nanoid(11)见 src/server/api.ts。generateCredentials玩家加入对局时被调用入参为 Koa 的ctx上下文可从请求头等生成定制凭证。源码中默认实现为() nanoid()src/server/auth.ts。authenticateCredentials玩家发起行动时被调用入参为客户端发送的credentials与行动者playerMetadata。默认实现areCredentialsAuthentic仅做字符串相等比较src/server/auth.ts。三者协作的完整链路Auth类src/server/auth.ts在generateCredentials或authenticateCredentials被自定义函数覆盖后前者直接替换默认生成逻辑后者替换校验逻辑并将shouldAuthenticate置为恒真即该对局强制鉴权。凭证会在POST /games/:name/:id/join时写入玩家元数据src/server/api.ts后续 socket 传输与 Lobby 操作leave/update/playAgain均通过Auth.authenticateCredentials校验。三、返回值run、kill、app、db、routerServer(...)返回一个对象包含五个成员成员类型说明runfunction启动服务器(portOrConfig, callback) ({ apiServer, appServer })killfunction停止服务器({ apiServer, appServer }) voidappobjectKoa 应用实例dbobject数据库实现实例routerobject服务端 API 的 Koa Router 实例run的实现src/server/index.ts值得细读它先await db.connect()连接数据库再根据lobbyConfig.apiPort决定 Lobby API 与游戏服务是否分端口部署最后分别listen并返回{ apiServer, appServer }——这两个句柄正是kill的参数。kill依次关闭 API 服务与主服务src/server/index.ts。四、五种启动方式4.1 基础启动const { Server, Origins } require(boardgame.io/server); const server Server({ // Provide the definitions for your game(s). games: [game1, game2, ...], // Provide the database storage class to use. db: new DbConnector(), origins: [ // Allow your game site to connect. https://www.mygame.domain, // Allow localhost to connect, except when NODE_ENV is production. Origins.LOCALHOST_IN_DEVELOPMENT, ], }); server.run(8000);要点games与origins为必填db省略时按 2.3 节规则自动选择存储Origins.LOCALHOST_IN_DEVELOPMENT生产环境自动失效。4.2 带启动回调server.run(8000, () console.log(server running...));回调在服务器成功监听端口后触发源码中serverRunConfig.callback在app.listen完成后调用见 src/server/index.ts。run也支持直接传入对象形式server.run({ port: 8000, callback })二者等价createServerRunConfig会合并两种入参见 src/server/index.ts。4.3 独立 Lobby API 端口const lobbyConfig { apiPort: 8080, apiCallback: () console.log(Running Lobby API on port 8080...), }; server.run({ port: 8000, lobbyConfig });lobbyConfig的两个选项apiPort指定后Lobby API 在独立的 Koa 服务器上以该端口运行否则与游戏服务共用默认端口。apiCallback独立 API 服务器就绪后调用仅当指定了apiPort时生效。源码中的实现路径src/server/index.ts未指定apiPort时在同一个 Koa 应用上configureApp(app, router, apiOrigins)指定时新建api应用、单独listen(apiPort)并打印API serving on port...日志。此时返回值中的apiServer即为该独立实例可通过kill({ apiServer, appServer })一并关闭。4.4 HTTPS 启动const { Server } require(boardgame.io/server); const fs require(fs); const server Server({ games: [game1, game2, ...], https: { cert: fs.readFileSync(/path/to/cert), key: fs.readFileSync(/path/to/key), }, }); server.run(8000);https选项直接透传给 socket.io 的 TLS 层io.attach(app, !!this.https, this.https)见 src/server/transport/socketio.ts类型为 Node 的https.ServerOptionscert/key必填字段含义与 Nodehttps模块一致。适合已有证书文件的正式部署场景。4.5 自定义认证generateCredentials在玩家加入对局时被调用入参为ctxKoa 上下文对象可读取请求头生成定制凭证authenticateCredentials在玩家行动时被调用入参为credentials客户端发送的凭证与playerMetadata发起行动玩家的元数据对象。官方示例const { Server } require(boardgame.io/server); const generateCredentials async ctx { const authHeader ctx.request.headers[authorization]; const token await authService.decodeToken(authHeader); return token.uid; } const authenticateCredentials async (credentials, playerMetadata) { if (credentials) { const token await authService.decodeToken(credentials); if (token.uid playerMetadata.credentials) return true; } return false; } const server Server({ games: [game1, game2, ...], generateCredentials, authenticateCredentials, }); server.run(8000);该示例的流程generateCredentials读取Authorization请求头并解码 token把其中的公开用户 ID 作为“凭证”存入游戏元数据authenticateCredentials收到客户端凭证后解码同样的 token比对解码出的uid与元数据中存储的凭证是否一致。这实现了“无密码、token 即凭证”的鉴权模型。结合源码补充两点实现细节authenticateCredentials只在匹配确实需要鉴权时才被调用。Auth.authenticateCredentials的逻辑是若匹配元数据中没有任何玩家凭证doesMatchRequireAuthentication为假则直接放行而一旦自定义了authenticateCredentialsshouldAuthenticate恒为真该匹配即强制鉴权src/server/auth.tssocket.io 传输层的sync与update事件都会携带凭证并通过Master走同一套鉴权src/server/transport/socketio.tsLobby 的leave、update、playAgain接口同样要求凭证见 src/server/api.ts。⚠️ 官方文档明确提示上述自定义认证方式目前与 ReactLobby组件的凭证提供机制不兼容请确认你的客户端接入方式后再采用。五、扩展服务端自定义路由与中间件boardgame.io 服务端基于 Koa。5.1 新增自定义路由const server Server({ /* options */ }); server.router.get(/custom-endpoint, (ctx, next) { ctx.body Hello World!; }); server.run(8000);router即new Router()src/server/index.ts在run()中通过configureRouter(...)注册到应用src/server/index.ts。你可以在调用run前任意添加GET/POST等路由它们会与内置 Lobby 路由共存。5.2 为既有路由添加中间件const server Server({ /* options */ }); // Add middleware to the create game route. server.router.use(/games/:name/create, async (ctx, next) { // Decide number of players etc. based on some other API. const { numPlayers, setupData } await fetchDataFromSomeCustomAPI(); // Set request body to be used by the create game route. ctx.request.body.numPlayers numPlayers; ctx.request.body.setupData setupData; next(); }); server.run(8000);该示例展示了中间件的典型用途在POST /games/:name/create命中内置处理器之前先从你自己的外部 API 拉取numPlayers与setupData并写入ctx.request.body从而覆盖创建对局的参数。内置创建路由会读取ctx.request.body中的setupData、unlisted、numPlayers并对numPlayers做合法性校验须在game.minPlayers/game.maxPlayers范围内否则返回 400见 src/server/api.ts。5.3 内置 Lobby 路由一览configureRouter注册的完整路由src/server/api.ts方法路径用途GET/games列出服务端支持的游戏名POST/games/:name/create创建新对局返回matchIDGET/games/:name列出某游戏的对局支持isGameover、updatedBefore、updatedAfter查询参数unlisted对局不返回GET/games/:name/:id获取指定对局详情POST/games/:name/:id/join加入对局返回playerID与playerCredentialsPOST/games/:name/:id/leave离开对局无剩余玩家时清空对局POST/games/:name/:id/playAgain基于旧对局创建新对局返回nextMatchIDPOST/games/:name/:id/update更新玩家名称与附加数据/rename已废弃提示改用本接口这些端点与 Lobby 客户端 API 一一对应完整的请求/响应参数说明见 Lobby.md。此外configureApp还会附加两层全局中间件src/server/api.tsCORS 中间件根据origins/apiOrigins动态设置Access-Control-Allow-OriginAPI_SECRET 守卫若设置了环境变量API_SECRET所有请求必须携带同值的api-secret请求头否则返回 403。六、与其他模块的衔接客户端Server仅在客户端multiplayer: true时必需客户端通过 socket.io 传输层连接sync/update/chat事件见 src/server/transport/socketio.ts。游戏定义games数组中的每个元素遵循 Game API。存储数据库连接器接口与自研适配器编写指南见 storage.md。Lobby 客户端服务端托管的 REST API 可通过LobbyClientboardgame.io/client或 ReactLobby组件消费详见 Lobby.md。部署前后端同服托管、生产环境NODE_ENV与origins的配合、HTTPS 等完整部署方案见 deployment.md。七、常见问题与注意事项CORS 403origins未设置或未包含客户端所在来源时浏览器请求会被拒绝。注意Origins.LOCALHOST_IN_DEVELOPMENT在生产环境自动为false此时必须显式列出生产域名。内存存储数据丢失未配置db且未设置FLATFILE_DIR时使用InMemory服务器重启后对局消失持久化请使用FlatFile或第三方适配器。凭证泄露风险playerCredentials仅在join时返回一次服务端元数据中的credentials字段在返回给客户端的响应中会被剥离createClientMatchData见 src/server/api.ts请妥善保存客户端凭证。API 密钥生产环境建议设置API_SECRET环境变量为 Lobby API 增加一层整体防护。自定义认证与 React Lobby 的兼容性文档明确提示当前实现与 ReactLobby的凭证机制不兼容接入前需确认客户端形态。通过本文覆盖的参数、启动方式与扩展点配合 src/server/index.ts 与 src/server/api.ts 等源码你可以完整掌控 boardgame.io 服务端的搭建、加固与定制。赞分享游戏开发【免费下载链接】boardgame.ioState Management and Multiplayer Networking for Turn-Based Games项目地址https://gitcode.com/gh_mirrors/bo/boardgame.io点击查看免费下载相关推荐boardgame.io 服务器端配置与扩展指南boardgame.io 服务器端配置与扩展指南 概述 boardgame.io 是一个用于构建回合制游戏的框架其服务器端组件负责管理多人游戏状态同步和游戏会游戏开发在 docker-minecraft-server 中运行 Bukkit/Spigot 服务端完整配置指南在 docker minecraft server 中运行 Bukkit/Spigot 服务端完整配置指南 导读 本文讲解如何在 docker minecra游戏开发后端在自定义命名空间中运行 Velero服务端部署与客户端配置完整指南在自定义命名空间中运行 Velero服务端部署与客户端配置完整指南 导读 本文基于 Velero 0.7.0 及以后版本引入的能力完整讲解如何让 Veler云原生灾备存储后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表