跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

存储与同步状态

最后更新 查看 MarkdownAgent 设置

Agent 类会安装 State 功能并将其连接到 WebSocket。每个 Agent 有一个状态值:它存储在 SQLite 中,可以在重启和休眠后继续存在,并同步到每个已连接的 client。本页介绍 Agent API。有关状态的存储和同步方式,请参阅 State 功能。

初始状态

import { Agent } from "agents";

export class GameAgent extends Agent {
	initialState = { players: [], status: "waiting" };

	// Runs before a change is stored. Throw to reject it.
	validateStateChange(next, source) {
		if (source !== "server" && next.status !== this.state.status) {
			throw new Error("Only the server can change the game status");
		}
	}

	// Runs after a change is stored and broadcast.
	onStateChanged(state, source) {
		if (source !== "server" && state.players.length >= 2) {
			this.setState({ ...state, status: "playing" });
		}
	}

	addPlayer(name) {
		this.setState({ ...this.state, players: [...this.state.players, name] });
	}
}
import { Agent, type Connection } from "agents";

type GameState = {
	players: string[];
	status: "waiting" | "playing";
};

export class GameAgent extends Agent<Env, GameState> {
	initialState: GameState = { players: [], status: "waiting" };

	// Runs before a change is stored. Throw to reject it.
	validateStateChange(next: GameState, source: Connection | "server") {
		if (source !== "server" && next.status !== this.state.status) {
			throw new Error("Only the server can change the game status");
		}
	}

	// Runs after a change is stored and broadcast.
	onStateChanged(state: GameState, source: Connection | "server") {
		if (source !== "server" && state.players.length >= 2) {
			this.setState({ ...state, status: "playing" });
		}
	}

	addPlayer(name: string) {
		this.setState({ ...this.state, players: [...this.state.players, name] });
	}
}

initialState 在 Agent 首次读取状态时应用。之后,this.state 会返回存储的值。状态必须可以进行 JSON serialization。

与 client 同步

useAgent 会接收每次更改,也可以使用 setState() 推送自己的更改。client 更改在存储之前会经过 validateStateChange():

import { useAgent } from "agents/react";

export function Lobby() {
	const agent = useAgent<{ players: string[]; status: string }>({
		agent: "GameAgent",
		name: "game-1",
	});
	return <p>{agent.state?.players.length ?? 0} players</p>;
}

API

成员 说明
initialState 新 Agent 的默认值
this.state 当前值
this.setState(state) 存储该值并广播给 client
validateStateChange(next, source) 存储更改前进行同步检查。抛出异常可拒绝更改
onStateChanged(state, source) 更改后运行。source 为 "server" 或 client 的 Connection

在 onStateChanged() 中,如果从其内部调用 setState(),请忽略 source 为 "server" 的更改,否则会形成循环。

对于不需要传递到 client 的数据,请通过 this.sql 使用 SQLite。对于 client 只能读取的值,请将其连接设为只读。

从 Workflow 更新状态

Workflow step 可以更改其 Agent 状态。这些调用是持久的,因此 Workflow 重试时不会重复执行:

方法 说明
step.updateAgentState(state) 替换状态
step.mergeAgentState(partial) 将字段合并到状态中
step.resetAgentState() 将状态重置为 initialState

后续步骤

State 功能

如何在任何 Durable Object 上验证、存储和同步状态。

这篇文档对您有帮助吗?