【免费下载链接】partykit
PartyKit simplifies developing multiplayer applications
项目地址:
https://gitcode.com/gh_mirrors/pa/partykit
点击查看 免费下载
PartyKit 是一个用于简化实时与多人应用开发的部署和托管平台,其核心交付物是一类全局分布式、有状态、按需创建、可编程的 Web 服务器(每个服务器实例称为一个 Party)。本文以官方文档 how-partykit-works.md 为主线,结合仓库源码与配置实例,逐层拆解 PartyKit 的运行时代理、服务器生命周期模型、HTTP/WebSocket 双协议接入方式,以及状态管理与横向扩展的实现原理,帮助读者完整掌握 PartyKit 应用从编写、部署到运行的底层机制。
一、概述:PartyKit 到底是什么
PartyKit 本质上是一个面向实时应用的 Web 服务器托管平台,它把传统需要自行运维、手动扩缩容的服务器,抽象成四个核心能力:
- 可编程(Programmable):你使用 Party.Server JS/TS API 实现服务器端业务逻辑;
- 可部署(Deployable):通过 partykit CLI 将服务器代码部署到 PartyKit 运行时;
- 可托管(Hosted):PartyKit 运行时负责承载、路由和扩缩容这些服务器。
也就是说,开发者只需要关心“实现服务器逻辑”和“执行部署命令”这两件事,其余的基础设施问题(进程调度、网络路由、数据持久化)全部交给平台。
二、PartyKit 运行时:基于 workerd 的现代化 JS 环境
PartyKit 运行时是一个基于现代 Web 标准的 JavaScript 环境,它构建在 Cloudflare 的 workerd 运行时之上——即驱动 Cloudflare Workers 的同一套运行时。
这个选择带来三个关键收益:
三、PartyKit 服务器:拆解四个关键属性
官方文档用四个形容词定义了 PartyKit 服务器(Party)的本质。下面逐一展开,并补充仓库源码层面的证据。
3.1 Web server:标准协议接入
每个 Party 底层都由一个 Cloudflare Durable Object 支撑(见 glossary.md 中对 Durable Object 的定义:运行在边缘、带持久状态、可无限扩展的 Worker 代码单元)。你可以用标准的 HTTP 请求与 Party 通信:
fetch(`https://${project}.${user}.partykit.dev/parties/main/${id}`, {
method: "GET"
});
更有价值的是,你可以用标准 WebSocket 连接到 Party,实现客户端与房间(Party 实例)之间的实时双向推送:
new WebSocket(`https://${project}.${user}.partykit.dev/parties/main/${id}`);
URL 路径 parties/main/${id} 中,main 是默认 Party 名称(每个项目的主 Party),id 是房间 ID。因为协议是标准的,你可以从浏览器、原生移动应用、嵌入式设备等任何具备 HTTP/WebSocket 能力的终端接入。官方还提供了可选客户端 SDK,例如 PartySocket(JS/TS 客户端),它封装了自动重连、消息缓冲、连接超时处理等能力。
从源码看,Party 的请求路由结构在 partyserver-api.md 中有完整定义:Room.id 就是 Party URL 中 /parties/:name/:id 的 :id 段,而 Party 名称则由 partykit.json 中的 parties 字段声明。
3.2 Programmable:完全可编程的服务器逻辑
与多数托管实时平台“服务端行为不可定制”不同,PartyKit 允许你编写任意业务逻辑,也可以直接使用开源生态中成熟的 npm 包来实现常见工作流。一个典型的 Party.Server 类实现如下(完整示例见 examples/class/src/server.ts):
import type * as Party from "partykit/server";
export default class Server implements Party.Server {
constructor(readonly room: Party.Room) {}
onRequest(req: Party.Request) {
return new Response("Hello via HTTP");
}
onConnect(connection: Party.Connection) {
connection.send("Hello via WebSockets");
}
onMessage(message: string) {
this.room.broadcast(`Received ${message} via WebSockets`);
}
}
从仓库源码 packages/partykit/src/server.ts 可以看到 Party.Server 接口定义了完整的生命周期方法集合:
- onStart:服务器启动或从休眠中唤醒后、首次 onConnect/onRequest 之前调用,适合从存储加载数据、做异步初始化;
- onConnect:新的 WebSocket 连接建立时调用,接收 Party.Connection 与 Party.ConnectionContext;
- onMessage:收到客户端或其他 Party 的消息时调用,消息类型为 string | ArrayBuffer;
- onRequest:收到 HTTP 请求时调用,需返回标准 Fetch API 的 Response;
- onClose / onError:连接关闭或出错时调用;
- onAlarm:定时告警触发时调用;
- getConnectionTags:为连接打标签,便于用 Room.getConnections(tag) 精准筛选。
此外,类上还可以定义 static 方法(通过 Server satisfies Party.Worker 做类型校验),构成 Party.Worker 接口:onFetch(处理不匹配 Party URL 的 HTTP 请求)、onSocket(处理不匹配 Party URL 的 WebSocket)、onBeforeRequest / onBeforeConnect(在边缘 Worker 中就近拦截并改写请求)、onCron(定时任务)。这些静态方法运行在靠近用户的边缘 Worker,而非房间内部,因此只能通过 Party.Lobby / Party.FetchLobby 访问受限资源(如 env、parties、ai、vectorize),无法访问 Room.storage。
3.3 On-demand:按需创建、近乎零启动
传统 Web 服务器需要预先配置、手动扩缩容,而 PartyKit 可以按需创建实例。关键在于每个 Party 都有一个唯一 id:
fetch(`https://${project}.${user}.partykit.dev/parties/main/${id}`);
这个 id 可以是任意字符串,实践中通常对应你要赋予实时/多人特性的文档、项目、房间、用户等实体的 ID。PartyKit 运行时根据 id 做请求路由,并保证:
- 使用相同 id 连接时,请求总是路由到同一个房间(同一个 Party 服务器实例);
- 使用新的唯一 id 连接时,平台会为你新建一个服务器实例。
Party 非常轻量,官方文档指出其启动时间几乎为零,这一点与 serverless 函数类似——只不过它比 serverless 多了一个决定性差异:有状态。
3.4 Stateful:像普通类一样管理状态
这是 Party 与 serverless 函数最本质的区别:每个房间是有状态的,你可以像在任何 TypeScript/JavaScript 类中一样维护状态:
export default class Server implements Party.Server {
messages: string[] = [];
onMessage(message: string) {
// 在内存中记录消息
this.messages.push(message);
// 广播给所有已连接客户端
this.room.broadcast(JSON.stringify({ messages: [message] }));
}
onConnect(connection: Party.Connection) {
// 新客户端连入时,把完整历史发送给它
connection.send(JSON.stringify({ messages: this.messages }));
}
}
这种编程模型可行的原因,在源码层面有明确依据:
- 每个 Party 运行在独立的 Durable Object 中,与任何其他进程完全隔离;
- PartyKit 保证相同 id 的请求/连接总是路由到同一个房间实例。
因此,你可以把每个 Party 当作一个单租户应用来编写——不需要处理分布式锁、跨节点同步等复杂问题,相比传统有状态 Web 服务器的编程模型极大简化。
需要指出的是,纯内存状态在服务器重启后会丢失。官方文档 persisting-state-into-storage.md 明确:服务器重启可能发生在重新部署、启用 Hibernation 后空闲休眠、运行时异常(如硬件故障)或达到最大生命周期时。若需持久化,应使用每个房间自带的事务性 KV 存储 Room.storage(key 最大 2048 字节,value 为结构化克隆算法支持的类型、单值上限 128 KiB),典型模式是在 onStart 中加载、在 onMessage 中写入。
3.5 Globally distributed:全球分布与水平扩展
每个房间运行在 Cloudflare 边缘网络中独立的 Durable Object 里,平台可以在全球数百个数据中心中的任意位置按需创建服务器。由此带来:
- 可靠性:单点故障不会影响整个应用;
- 水平可扩展性:房间数量可以随并发规模增长;
- 低延迟:服务器总是在网络拓扑上距离客户端最近的数据中心创建,客户端与服务器之间的连接通常非常快——这正是 PartyKit 适合实时、延迟敏感场景的原因。
四、源码级实现印证:从用户代码到 PartyKit 运行时
为了理解“用户写的类”如何被平台执行,可以查看仓库中的门面(facade)层实现 packages/partykit/facade/worker.ts。该文件定义了统一的 PartyServerAPI 接口,并提供了两类适配器:
- ClassWorker:适配类式实现(export default class Server implements Party.Server)。它接收 Party.Worker 构造函数与 Party.Room,在构造时实例化用户类,并通过 this.options.hibernate === true 判定是否支持 Hibernation;
- ModuleWorker:适配旧式模块实现(export default {} satisfies PartyKitServer),把 onConnect、onMessage、onRequest 等回调转发给用户对象,并额外传入 room 参数。
两类适配器都实现了统一的 onStart、onConnect、onMessage、onClose、onError、onRequest、onAlarm、getConnectionTags 接口,这说明平台对两种写法是等价的——官方文档建议新项目优先使用类式 Party.Server API(见 partyserver-api.md 与旧版 partykitserver-legacy-api.md 的区别说明)。
4.1 配置与部署:partykit.json 与 CLI
PartyKit 项目的关键配置集中在 partykit.json(schema 定义见 config-schema.ts)。以仓库内置示例 examples/class/partykit.json 为例:
{
"name": "class-example",
"main": "src/server.ts",
"compatibilityDate": "2023-09-28",
"serve": {
"path": "public",
"build": "src/client.ts"
}
}
- name:项目名,用于生成 https://<name>.<user>.partykit.dev 域名;
- main:主 Party 入口文件,即实现 Party.Server 的模块;
- parties:额外声明的多 Party 映射(每个 Party 暴露在 /parties/:party/:room-id);
- serve:静态资源服务配置(path、build 及其 entry/bundle/minify/format 等 esbuild 选项);
- port / persist:本地开发服务器端口(默认 1999)与开发态存储持久化路径(默认 .partykit/state);
- vars(已弃用)与 define:环境变量与全局常量替换;
- compatibilityDate / compatibilityFlags:Cloudflare Workers API 兼容日期与标志;
- crons:定时任务调度(配合静态 onCron 使用,本地可用 http://localhost:1999/__scheduled__?cron=cron-name 调试)。
配套的 partykit CLI 提供完整工作流:npx partykit init(初始化项目)、npx partykit dev(本地热重载开发)、npx partykit deploy(部署上线)、npx partykit tail(追踪线上日志)、npx partykit list / delete(项目管理)、env 系列(环境变量管理)以及 login / logout / whoami / token generate(认证与 CI 部署令牌)。首次部署时若未登录,CLI 会自动引导通过 GitHub 授权,部署后域名格式为 [项目名].[GitHub 用户名].partykit.dev。
4.2 生命周期与请求路由的完整链路
综合官方文档与源码,一个 PartyKit 请求的完整链路是:
4.3 扩展方向:Hibernation 与规模上限
默认情况下,只要存在连接的 WebSocket,PartyKit 就会把 Party.Server 实例常驻内存。若要支撑更大规模连接,官方提供了 Hibernation 机制(见 scaling-partykit-servers-with-hibernation.mdx):
export default class Server implements Party.Server {
options: Party.ServerOptions = {
hibernate: true
};
}
Hibernation 的核心思想是:房间空闲时(不处理消息)由平台将 Party.Server 实例从内存卸载,但保持对客户端的连接,客户端无感知;一旦收到消息,平台重新实例化服务器并执行构造函数与 onStart。这样单个房间支持的连接数可从默认的约 100 个提升到约 32,000 个(实际上限取决于代码的内存与 CPU 表现,且每个房间的内存上限通常为 128MB)。对应地,启用 Hibernation 时应避免在 onStart 中全量加载状态,推荐“按需读取、多 key 分片”的模式,并改用 onMessage / onClose 生命周期方法(手动在 onConnect 中挂载的事件处理器在休眠后会丢失)。
五、结语
PartyKit 的价值在于把“分布式有状态实时服务器”这一复杂基础设施,压缩成“写一个类 + 一条部署命令”。其底层是 Cloudflare 边缘网络上的 Durable Object:按 id 路由实现按需创建与状态隔离,标准 HTTP/WebSocket 协议保证全终端可接入,Party.Server 生命周期 API 配合 Room.storage 与 Hibernation 机制,让开发者既能获得 serverless 的免运维体验,又能保留类式编程的状态管理便利。对于实时协作、多人游戏、直播互动等场景,这份 how-partykit-works.md 所描述的工作原理,正是理解所有 PartyKit 应用架构的起点。
赞
【免费下载链接】partykit
PartyKit simplifies developing multiplayer applications
项目地址:
https://gitcode.com/gh_mirrors/pa/partykit
点击查看 免费下载
相关推荐
深入解析Realtek 8812AU/8821AU Linux无线驱动部署
B站m4s转换器终极指南:一键解锁缓存视频的播放自由
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网硕互联帮助中心





评论前必须登录!
注册