本指南说明请求如何路由到 Agent、命名规则,以及组织 Agent 的模式。
请求到达时,routeAgentRequest() 解析 URL 并路由到相应 Agent 实例:
https://your-worker.dev/agents/{agent-name}/{instance-name}
└────┬────┘ └─────┬─────┘
Class name Unique instance ID
(kebab-case)示例 URL:
| URL | Agent 类 | 实例 |
|---|---|---|
/agents/counter/user-123 |
Counter |
user-123 |
/agents/chat-room/lobby |
ChatRoom |
lobby |
/agents/my-agent/default |
MyAgent |
default |
Agent 类名自动转换为 kebab-case 用于 URL:
| 类名 | URL 路径 |
|---|---|
Counter |
/agents/counter/... |
MyAgent |
/agents/my-agent/... |
ChatRoom |
/agents/chat-room/... |
AIAssistant |
/agents/ai-assistant/... |
路由器同时匹配原始名与 kebab-case 版本,因此两者均可使用:
useAgent({ agent: "Counter" })→/agents/counter/...useAgent({ agent: "counter" })→/agents/counter/...
routeAgentRequest() 是 Agent 路由的主入口:
import { routeAgentRequest } from "agents";
export default {
async fetch(request, env, ctx) {
// Route to agents - returns Response or undefined
const agentResponse = await routeAgentRequest(request, env);
if (agentResponse) {
return agentResponse;
}
// No agent matched - handle other routes
return new Response("Not found", { status: 404 });
},
};import { routeAgentRequest } from "agents";
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
// Route to agents - returns Response or undefined
const agentResponse = await routeAgentRequest(request, env);
if (agentResponse) {
return agentResponse;
}
// No agent matched - handle other routes
return new Response("Not found", { status: 404 });
},
} satisfies ExportedHandler<Env>;实例名(URL 最后一段)决定由哪个 Agent 实例处理请求。每个唯一名称对应独立 Agent 与独立 state。
每个用户拥有独立 Agent 实例:
// Client
const agent = useAgent({
agent: "UserProfile",
name: `user-${userId}`, // e.g., "user-abc123"
});// Client
const agent = useAgent({
agent: "UserProfile",
name: `user-${userId}`, // e.g., "user-abc123"
});/agents/user-profile/user-abc123 → User abc123's agent
/agents/user-profile/user-xyz789 → User xyz789's agent (separate instance)多个用户共享同一 Agent 实例:
// Client
const agent = useAgent({
agent: "ChatRoom",
name: roomId, // e.g., "general" or "room-42"
});// Client
const agent = useAgent({
agent: "ChatRoom",
name: roomId, // e.g., "general" or "room-42"
});/agents/chat-room/general → All users in "general" share this agent整个应用的全局单例:
// Client
const agent = useAgent({
agent: "AppConfig",
name: "default", // Or any consistent name
});// Client
const agent = useAgent({
agent: "AppConfig",
name: "default", // Or any consistent name
});根据上下文生成实例名:
// Per-session
const agent = useAgent({
agent: "Session",
name: sessionId,
});
// Per-document
const agent = useAgent({
agent: "Document",
name: `doc-${documentId}`,
});
// Per-game
const agent = useAgent({
agent: "Game",
name: `game-${gameId}-${Date.now()}`,
});// Per-session
const agent = useAgent({
agent: "Session",
name: sessionId,
});
// Per-document
const agent = useAgent({
agent: "Document",
name: `doc-${documentId}`,
});
// Per-game
const agent = useAgent({
agent: "Game",
name: `game-${gameId}-${Date.now()}`,
});需要控制 URL 结构的高级场景可绕过默认 /agents/{agent}/{name} 模式。
basePath 选项允许客户端连接任意 URL 路径:
// Client connects to /user instead of /agents/user-agent/...
const agent = useAgent({
agent: "UserAgent", // Required but ignored when basePath is set
basePath: "user", // → connects to /user
});// Client connects to /user instead of /agents/user-agent/...
const agent = useAgent({
agent: "UserAgent", // Required but ignored when basePath is set
basePath: "user", // → connects to /user
});适用于以下情况:
- 需要无
/agents/前缀的简洁 URL - 实例名由服务端决定(例如来自 auth/session)
- 与现有 URL 结构集成
使用 basePath 时服务端须处理路由。用 getAgentByName() 获取 Agent 实例,再用 fetch() 转发请求:
export default {
async fetch(request, env) {
const url = new URL(request.url);
// Custom routing - server determines instance from session
if (url.pathname.startsWith("/user/")) {
const session = await getSession(request);
const agent = await getAgentByName(env.UserAgent, session.userId);
return agent.fetch(request); // Forward request directly to agent
}
// Default routing for standard /agents/... paths
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
};export default {
async fetch(request: Request, env: Env) {
const url = new URL(request.url);
// Custom routing - server determines instance from session
if (url.pathname.startsWith("/user/")) {
const session = await getSession(request);
const agent = await getAgentByName(env.UserAgent, session.userId);
return agent.fetch(request); // Forward request directly to agent
}
// Default routing for standard /agents/... paths
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;将不同路径路由到不同实例:
// Route /chat/{room} to ChatRoom agent
if (url.pathname.startsWith("/chat/")) {
const roomId = url.pathname.replace("/chat/", "");
const agent = await getAgentByName(env.ChatRoom, roomId);
return agent.fetch(request);
}
// Route /doc/{id} to Document agent
if (url.pathname.startsWith("/doc/")) {
const docId = url.pathname.replace("/doc/", "");
const agent = await getAgentByName(env.Document, docId);
return agent.fetch(request);
}// Route /chat/{room} to ChatRoom agent
if (url.pathname.startsWith("/chat/")) {
const roomId = url.pathname.replace("/chat/", "");
const agent = await getAgentByName(env.ChatRoom, roomId);
return agent.fetch(request);
}
// Route /doc/{id} to Document agent
if (url.pathname.startsWith("/doc/")) {
const docId = url.pathname.replace("/doc/", "");
const agent = await getAgentByName(env.Document, docId);
return agent.fetch(request);
}使用 basePath 时,客户端在服务端返回信息前不知连到哪个实例。Agent 在连接时自动发送 identity:
const agent = useAgent({
agent: "UserAgent",
basePath: "user",
onIdentity: (name, agentType) => {
console.log(`Connected to ${agentType} instance: ${name}`);
// e.g., "Connected to user-agent instance: user-123"
},
});
// Reactive state - re-renders when identity is received
return (
<div>
{agent.identified ? `Connected to: ${agent.name}` : "Connecting..."}
</div>
);const agent = useAgent({
agent: "UserAgent",
basePath: "user",
onIdentity: (name, agentType) => {
console.log(`Connected to ${agentType} instance: ${name}`);
// e.g., "Connected to user-agent instance: user-123"
},
});
// Reactive state - re-renders when identity is received
return (
<div>
{agent.identified ? `Connected to: ${agent.name}` : "Connecting..."}
</div>
);对于 AgentClient:
const agent = new AgentClient({
agent: "UserAgent",
basePath: "user",
host: "example.com",
onIdentity: (name, agentType) => {
// Update UI with actual instance name
setInstanceName(name);
},
});
// Wait for identity before proceeding
await agent.ready;
console.log(agent.name); // Now has the server-determined nameconst agent = new AgentClient({
agent: "UserAgent",
basePath: "user",
host: "example.com",
onIdentity: (name, agentType) => {
// Update UI with actual instance name
setInstanceName(name);
},
});
// Wait for identity before proceeding
await agent.ready;
console.log(agent.name); // Now has the server-determined name若重连时 identity 变化(例如 session 过期后以他人身份登录),可用 onIdentityChange 处理:
const agent = useAgent({
agent: "UserAgent",
basePath: "user",
onIdentityChange: (oldName, newName, oldAgent, newAgent) => {
console.log(`Session changed: ${oldName} → ${newName}`);
// Refresh state, show notification, etc.
},
});const agent = useAgent({
agent: "UserAgent",
basePath: "user",
onIdentityChange: (oldName, newName, oldAgent, newAgent) => {
console.log(`Session changed: ${oldName} → ${newName}`);
// Refresh state, show notification, etc.
},
});未提供 onIdentityChange 且 identity 变化时,会记录警告以帮助发现意外 session 变更。
若实例名含敏感数据(session ID、内部用户 ID),可禁用 identity 发送:
class SecureAgent extends Agent {
// Do not expose instance names to clients
static options = { sendIdentityOnConnect: false };
}class SecureAgent extends Agent {
// Do not expose instance names to clients
static options = { sendIdentityOnConnect: false };
}禁用 identity 时:
agent.identified保持falseagent.ready永不 resolve(改用 state 更新)- 永不调用
onIdentity与onIdentityChange
| 场景 | 方式 |
|---|---|
| 标准 Agent 访问 | 默认值 /agents/{agent}/{name} |
| 来自 auth/session 的实例 | basePath + getAgentByName + fetch |
简洁 URL(无 /agents/ 前缀) |
basePath + 自定义路由 |
| 旧版 URL 结构 | basePath + 自定义路由 |
| 复杂路由逻辑 | Worker 中自定义路由 |
routeAgentRequest() 与 getAgentByName() 均接受选项以自定义路由行为。
跨源请求时(前端在不同域上很常见):
const response = await routeAgentRequest(request, env, {
cors: true, // Enable default CORS headers
});const response = await routeAgentRequest(request, env, {
cors: true, // Enable default CORS headers
});或使用自定义 CORS 头:
const response = await routeAgentRequest(request, env, {
cors: {
"Access-Control-Allow-Origin": "https://myapp.com",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
},
});const response = await routeAgentRequest(request, env, {
cors: {
"Access-Control-Allow-Origin": "https://myapp.com",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
},
});对延迟敏感的应用,可提示 Agent 运行位置:
// With getAgentByName
const agent = await getAgentByName(env.MyAgent, "instance-name", {
locationHint: "enam", // Eastern North America
});
// With routeAgentRequest (applies to all matched agents)
const response = await routeAgentRequest(request, env, {
locationHint: "enam",
});// With getAgentByName
const agent = await getAgentByName(env.MyAgent, "instance-name", {
locationHint: "enam", // Eastern North America
});
// With routeAgentRequest (applies to all matched agents)
const response = await routeAgentRequest(request, env, {
locationHint: "enam",
});可用 location hint:wnam、enam、sam、weur、eeur、apac、oc、afr、me
满足数据驻留要求时:
// With getAgentByName
const agent = await getAgentByName(env.MyAgent, "instance-name", {
jurisdiction: "eu", // EU jurisdiction
});
// With routeAgentRequest (applies to all matched agents)
const response = await routeAgentRequest(request, env, {
jurisdiction: "eu",
});// With getAgentByName
const agent = await getAgentByName(env.MyAgent, "instance-name", {
jurisdiction: "eu", // EU jurisdiction
});
// With routeAgentRequest (applies to all matched agents)
const response = await routeAgentRequest(request, env, {
jurisdiction: "eu",
});Agent 由运行时实例化而非直接构造,props 用于传递初始化参数:
const agent = await getAgentByName(env.MyAgent, "instance-name", {
props: {
userId: session.userId,
config: { maxRetries: 3 },
},
});const agent = await getAgentByName(env.MyAgent, "instance-name", {
props: {
userId: session.userId,
config: { maxRetries: 3 },
},
});props 传给 Agent 的 onStart 生命周期方法:
class MyAgent extends Agent {
userId;
config;
async onStart(props) {
this.userId = props?.userId;
this.config = props?.config;
}
}class MyAgent extends Agent<Env, State> {
private userId?: string;
private config?: { maxRetries: number };
async onStart(props?: { userId: string; config: { maxRetries: number } }) {
this.userId = props?.userId;
this.config = props?.config;
}
}与 routeAgentRequest 一起使用 props 时,相同 props 传给匹配 URL 的 Agent。适用于认证等通用上下文:
export default {
async fetch(request, env) {
const session = await getSession(request);
return routeAgentRequest(request, env, {
props: { userId: session.userId, role: session.role },
});
},
};export default {
async fetch(request, env) {
const session = await getSession(request);
return routeAgentRequest(request, env, {
props: { userId: session.userId, role: session.role },
});
},
} satisfies ExportedHandler<Env>;Agent 特定初始化请改用 getAgentByName,由你精确控制哪个 Agent 接收 props。
服务端代码应对 transient Durable Object 路由失败重试时,将 routingRetry 与 getAgentByName() 一起使用:
const agent = await getAgentByName(env.MyAgent, "instance-name", {
routingRetry: {
maxAttempts: 3,
},
});const agent = await getAgentByName(env.MyAgent, "instance-name", {
routingRetry: {
maxAttempts: 3,
},
});此选项适用于请求转发与 RPC 路径,短暂路由失败应在向调用方返回错误前重试。
routeAgentRequest 支持 hook,在请求到达 Agent 前拦截:
const response = await routeAgentRequest(request, env, {
onBeforeConnect: (req, lobby) => {
// Called before WebSocket connections
// Return a Response to reject, Request to modify, or void to continue
},
onBeforeRequest: (req, lobby) => {
// Called before HTTP requests
// Return a Response to reject, Request to modify, or void to continue
},
});const response = await routeAgentRequest(request, env, {
onBeforeConnect: (req, lobby) => {
// Called before WebSocket connections
// Return a Response to reject, Request to modify, or void to continue
},
onBeforeRequest: (req, lobby) => {
// Called before HTTP requests
// Return a Response to reject, Request to modify, or void to continue
},
});这些 hook 适用于认证与校验。详细示例见 跨域身份验证。
可在 Worker 代码中使用 getAgentByName() 访问 Agent 以进行 RPC 调用:
import { getAgentByName, routeAgentRequest } from "agents";
export default {
async fetch(request, env) {
const url = new URL(request.url);
// API endpoint that interacts with an agent
if (url.pathname === "/api/increment") {
const counter = await getAgentByName(env.Counter, "global-counter");
const newCount = await counter.increment();
return Response.json({ count: newCount });
}
// Regular agent routing
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
};import { getAgentByName, routeAgentRequest } from "agents";
export default {
async fetch(request: Request, env: Env) {
const url = new URL(request.url);
// API endpoint that interacts with an agent
if (url.pathname === "/api/increment") {
const counter = await getAgentByName(env.Counter, "global-counter");
const newCount = await counter.increment();
return Response.json({ count: newCount });
}
// Regular agent routing
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;关于 locationHint、jurisdiction 与 props 等选项,请参阅路由选项。
请求可在实例名后包含子路径。这些会传给 Agent 的 onRequest() handler:
/agents/api/v1/users → agent: "api", instance: "v1", path: "/users"
/agents/api/v1/users/123 → agent: "api", instance: "v1", path: "/users/123"在 Agent 中处理子路径:
export class API extends Agent {
async onRequest(request) {
const url = new URL(request.url);
// url.pathname contains the full path including /agents/api/v1/...
// Extract the sub-path after your agent's base path
const path = url.pathname.replace(/^\/agents\/api\/[^/]+/, "");
if (request.method === "GET" && path === "/users") {
return Response.json(await this.getUsers());
}
if (request.method === "POST" && path === "/users") {
const data = await request.json();
return Response.json(await this.createUser(data));
}
return new Response("Not found", { status: 404 });
}
}export class API extends Agent {
async onRequest(request: Request): Promise<Response> {
const url = new URL(request.url);
// url.pathname contains the full path including /agents/api/v1/...
// Extract the sub-path after your agent's base path
const path = url.pathname.replace(/^\/agents\/api\/[^/]+/, "");
if (request.method === "GET" && path === "/users") {
return Response.json(await this.getUsers());
}
if (request.method === "POST" && path === "/users") {
const data = await request.json();
return Response.json(await this.createUser(data));
}
return new Response("Not found", { status: 404 });
}
}一个项目可有多个 Agent 类。每个拥有独立 namespace:
// server.ts
export { Counter } from "./agents/counter";
export { ChatRoom } from "./agents/chat-room";
export { UserProfile } from "./agents/user-profile";
export default {
async fetch(request, env) {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
};// server.ts
export { Counter } from "./agents/counter";
export { ChatRoom } from "./agents/chat-room";
export { UserProfile } from "./agents/user-profile";
export default {
async fetch(request: Request, env: Env) {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;{
"durable_objects": {
"bindings": [
{ "name": "Counter", "class_name": "Counter" },
{ "name": "ChatRoom", "class_name": "ChatRoom" },
{ "name": "UserProfile", "class_name": "UserProfile" },
],
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["Counter", "ChatRoom", "UserProfile"],
},
],
}[[durable_objects.bindings]]
name = "Counter"
class_name = "Counter"
[[durable_objects.bindings]]
name = "ChatRoom"
class_name = "ChatRoom"
[[durable_objects.bindings]]
name = "UserProfile"
class_name = "UserProfile"
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "Counter", "ChatRoom", "UserProfile" ]每个 Agent 通过各自路径访问:
/agents/counter/...
/agents/chat-room/...
/agents/user-profile/...请求在系统中的流转如下:
flowchart TD
A["HTTP 请求<br/>或 WebSocket"] --> B["routeAgentRequest<br/>解析 URL 路径"]
B --> C["按名称在 env 中<br/>查找 binding"]
C --> D["按实例 ID<br/>获取/创建 DO"]
D --> E["Agent 实例"]
E --> F{"协议?"}
F -->|WebSocket| G["onConnect(), onMessage"]
F -->|HTTP| H["onRequest()"]
在请求到达 Agent 前有多种认证方式。
routeAgentRequest() 提供 onBeforeConnect 与 onBeforeRequest hook 用于认证:
import { Agent, routeAgentRequest } from "agents";
export default {
async fetch(request, env) {
return (
(await routeAgentRequest(request, env, {
// Run before WebSocket connections
onBeforeConnect: async (request) => {
const token = new URL(request.url).searchParams.get("token");
if (!(await verifyToken(token, env))) {
// Return a response to reject the connection
return new Response("Unauthorized", { status: 401 });
}
// Return nothing to allow the connection
},
// Run before HTTP requests
onBeforeRequest: async (request) => {
const auth = request.headers.get("Authorization");
if (!auth || !(await verifyAuth(auth, env))) {
return new Response("Unauthorized", { status: 401 });
}
},
// Optional: prepend a prefix to agent instance names
prefix: "user-",
})) ?? new Response("Not found", { status: 404 })
);
},
};import { Agent, routeAgentRequest } from "agents";
export default {
async fetch(request: Request, env: Env) {
return (
(await routeAgentRequest(request, env, {
// Run before WebSocket connections
onBeforeConnect: async (request) => {
const token = new URL(request.url).searchParams.get("token");
if (!(await verifyToken(token, env))) {
// Return a response to reject the connection
return new Response("Unauthorized", { status: 401 });
}
// Return nothing to allow the connection
},
// Run before HTTP requests
onBeforeRequest: async (request) => {
const auth = request.headers.get("Authorization");
if (!auth || !(await verifyAuth(auth, env))) {
return new Response("Unauthorized", { status: 401 });
}
},
// Optional: prepend a prefix to agent instance names
prefix: "user-",
})) ?? new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;在调用 routeAgentRequest() 前检查认证:
export default {
async fetch(request, env) {
const url = new URL(request.url);
// Protect agent routes
if (url.pathname.startsWith("/agents/")) {
const user = await authenticate(request, env);
if (!user) {
return new Response("Unauthorized", { status: 401 });
}
// Optionally, enforce that users can only access their own agents
const instanceName = url.pathname.split("/")[3];
if (instanceName !== `user-${user.id}`) {
return new Response("Forbidden", { status: 403 });
}
}
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
};export default {
async fetch(request: Request, env: Env) {
const url = new URL(request.url);
// Protect agent routes
if (url.pathname.startsWith("/agents/")) {
const user = await authenticate(request, env);
if (!user) {
return new Response("Unauthorized", { status: 401 });
}
// Optionally, enforce that users can only access their own agents
const instanceName = url.pathname.split("/")[3];
if (instanceName !== `user-${user.id}`) {
return new Response("Forbidden", { status: 403 });
}
}
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;若使用 Hono ↗ 等框架,在调用 Agent 前于中间件中认证:
import { Agent, getAgentByName } from "agents";
import { Hono } from "hono";
const app = new Hono();
// Authentication middleware
app.use("/agents/*", async (c, next) => {
const token = c.req.header("Authorization")?.replace("Bearer ", "");
if (!token || !(await verifyToken(token, c.env))) {
return c.json({ error: "Unauthorized" }, 401);
}
await next();
});
// Route to a specific agent
app.all("/agents/code-review/:id/*", async (c) => {
const id = c.req.param("id");
const agent = await getAgentByName(c.env.CodeReviewAgent, id);
return agent.fetch(c.req.raw);
});
export default app;import { Agent, getAgentByName } from "agents";
import { Hono } from "hono";
const app = new Hono<{ Bindings: Env }>();
// Authentication middleware
app.use("/agents/*", async (c, next) => {
const token = c.req.header("Authorization")?.replace("Bearer ", "");
if (!token || !(await verifyToken(token, c.env))) {
return c.json({ error: "Unauthorized" }, 401);
}
await next();
});
// Route to a specific agent
app.all("/agents/code-review/:id/*", async (c) => {
const id = c.req.param("id");
const agent = await getAgentByName(c.env.CodeReviewAgent, id);
return agent.fetch(c.req.raw);
});
export default app;WebSocket 认证模式(URL 中的 token、JWT 刷新)见 跨域身份验证。
错误消息会列出可用 Agent。检查:
- Agent 类已从入口点导出。
- 代码中类名与
wrangler.jsonc中class_name一致。 - URL 使用正确的 kebab-case 名称。
- 确认 URL 模式:
/agents/{agent-name}/{instance-name}。 - 确认在 404 handler 之前调用
routeAgentRequest()。 - 确保返回(而非仅调用)
routeAgentRequest()的响应。
- 不要修改 WebSocket 升级的
routeAgentRequest()响应。 - 从不同源连接时确保启用 CORS。
- 在浏览器开发者工具中查看实际错误。
- 确保 Worker 处理自定义路径并转发到 Agent。
- 使用
getAgentByName()+agent.fetch(request)转发请求。 - 设置
basePath时agent参数仍必填但被忽略。 - 确认服务端路由与客户端
basePath一致。
将请求路由到相应 Agent。
| 参数 | 类型 | 描述 |
|---|---|---|
request |
Request |
传入请求 |
env |
Env |
含 Agent 绑定的环境 |
options.cors |
boolean | HeadersInit |
启用 CORS 头 |
options.props |
Record<string, unknown> |
传给处理请求的 Agent 的 props |
options.locationHint |
string |
Agent 实例的首选位置 |
options.jurisdiction |
string |
Agent 实例的数据管辖 |
options.onBeforeConnect |
Function |
WebSocket 连接前回调 |
options.onBeforeRequest |
Function |
HTTP 请求前回调 |
返回值: Promise<Response | undefined> — 匹配则返回 Response,无 Agent 路由则 undefined。
按名称获取 Agent 实例,用于服务端 RPC 或请求转发。
| 参数 | 类型 | 描述 |
|---|---|---|
namespace |
DurableObjectNamespace<T> |
来自 env 的 Agent 绑定 |
name |
string |
实例名 |
options.locationHint |
string |
首选位置 |
options.jurisdiction |
string |
数据管辖 |
options.props |
Record<string, unknown> |
传给 onStart 的初始化属性 |
options.routingRetry |
object |
transient Durable Object 路由失败的重试配置 |
返回值: Promise<DurableObjectStub<T>> — 用于调用 Agent 方法或转发请求的类型化 stub。
自定义路由的客户端连接选项:
| 选项 | 类型 | 描述 |
|---|---|---|
agent |
string |
Agent 类名(必填) |
name |
string |
实例名(默认:"default") |
basePath |
string |
完整 URL 路径 — 绕过 agent/name URL 构造 |
path |
string |
追加到 URL 的额外路径 |
onIdentity |
(name, agent) => void |
服务端发送 identity 时调用 |
onIdentityChange |
(oldName, newName, oldAgent, newAgent) => void |
重连时 identity 变化时调用 |
返回值属性(React hook):
| 属性 | 类型 | 描述 |
|---|---|---|
name |
string |
当前实例名(响应式) |
agent |
string |
当前 Agent 类名(响应式) |
identified |
boolean |
是否已收到 identity(响应式) |
ready |
Promise<void> |
收到 identity 时 resolve |
Agent 配置的静态选项:
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
hibernate |
boolean |
true |
不活跃时 Agent 是否应休眠 |
sendIdentityOnConnect |
boolean |
true |
连接时是否向客户端发送 identity |
hungScheduleTimeoutSeconds |
number |
30 |
运行中 schedule 被视为挂起前的超时 |
class SecureAgent extends Agent {
static options = { sendIdentityOnConnect: false };
}class SecureAgent extends Agent {
static options = { sendIdentityOnConnect: false };
}