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

HTTP 与 Server-Sent Events

最后更新 查看 MarkdownAgent 设置

请求到达 Durable Object 后,Lifecycle会先将其交给各项能力处理,然后调用你的 onRequest()。你可以用它实现 HTTP API,也可以通过服务器发送事件 (SSE) 流式传输响应。

处理 HTTP 请求

对象会收到完整 URL,因此请根据路径末尾进行匹配:

import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";

export class ApiAgent extends DurableObject {
	lifecycle = Lifecycle.install(this);

	async onRequest(request) {
		const url = new URL(request.url);

		if (url.pathname.endsWith("/status")) {
			return Response.json({ name: this.lifecycle.name, status: "ok" });
		}

		if (url.pathname.endsWith("/action")) {
			if (request.method !== "POST") {
				return new Response("Method not allowed", { status: 405 });
			}
			const { action } = await request.json();
			await this.ctx.storage.put("lastAction", action);
			return Response.json({ success: true });
		}

		return new Response("Not found", { status: 404 });
	}
}
import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";

export class ApiAgent extends DurableObject<Env> {
	readonly lifecycle = Lifecycle.install(this);

	async onRequest(request: Request): Promise<Response> {
		const url = new URL(request.url);

		if (url.pathname.endsWith("/status")) {
			return Response.json({ name: this.lifecycle.name, status: "ok" });
		}

		if (url.pathname.endsWith("/action")) {
			if (request.method !== "POST") {
				return new Response("Method not allowed", { status: 405 });
			}
			const { action } = await request.json<{ action: string }>();
			await this.ctx.storage.put("lastAction", action);
			return Response.json({ success: true });
		}

		return new Response("Not found", { status: 404 });
	}
}

如果没有 onRequest(),未被任何能力处理的请求会返回 404。如需从 Worker 访问对象,请参阅路由。

流式传输模型回复

从 onRequest() 返回流式响应。AI SDK 可以为你构建此响应:

import { DurableObject } from "cloudflare:workers";
import { streamText } from "ai";
import { Lifecycle } from "agents/lifecycle";
import { createAI } from "agents/models/ai-sdk";

export class ChatAgent extends DurableObject {
	lifecycle = Lifecycle.install(this);

	async onRequest(request) {
		const { prompt } = await request.json();
		const ai = createAI({ binding: this.env.AI });

		const result = streamText({
			model: ai("anthropic/claude-opus-5.5"),
			prompt,
		});

		return result.toTextStreamResponse();
	}
}
import { DurableObject } from "cloudflare:workers";
import { streamText } from "ai";
import { Lifecycle } from "agents/lifecycle";
import { createAI } from "agents/models/ai-sdk";

export class ChatAgent extends DurableObject<Env> {
	readonly lifecycle = Lifecycle.install(this);

	async onRequest(request: Request): Promise<Response> {
		const { prompt } = await request.json<{ prompt: string }>();
		const ai = createAI({ binding: this.env.AI });

		const result = streamText({
			model: ai("anthropic/claude-opus-5.5"),
			prompt,
		});

		return result.toTextStreamResponse();
	}
}

若要自行编写 SSE,请返回内容类型为 text/event-stream 的 ReadableStream。每个事件由一行或多行 field: value 字段组成,后跟一个空行:

event: update
id: 42
data: {"count": 42}

断开连接后恢复数据流

onRequest() 中的数据流会在客户端断开连接时结束,客户端也会丢失断开期间错过的内容。Streams 能力会存储每个数据块,而 sseResponse() 会以 SSE 形式提供已存储的数据流。重新连接的浏览器 EventSource 会发送 Last-Event-ID,响应则会从下一个数据块继续:

import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
import { Streams, sseResponse } from "agents/streams";

export class ReportAgent extends DurableObject {
	streams = new Streams();
	lifecycle = Lifecycle.install(this).use(this.streams);

	async onRequest(request) {
		const id = new URL(request.url).searchParams.get("id") ?? "report";
		return sseResponse(this.streams, id, { request });
	}
}
import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
import { Streams, sseResponse } from "agents/streams";

export class ReportAgent extends DurableObject<Env> {
	readonly streams = new Streams();
	readonly lifecycle = Lifecycle.install(this).use(this.streams);

	async onRequest(request: Request): Promise<Response> {
		const id = new URL(request.url).searchParams.get("id") ?? "report";
		return sseResponse(this.streams, id, { request });
	}
}

Streams 目前为实验性功能。有关生成数据块的信息,请参阅 Streams。

使用 WebSockets 还是 SSE

功能 WebSockets SSE
方向 两种方式均支持 服务器到客户端
协议 ws:// 或 wss:// HTTP
二进制数据 是 不支持,仅限文本
重连 由 useAgent 和 AgentClient 处理 由浏览器处理
适用场景 交互式应用、聊天、可调用方法 流式回复、通知

对于 WebSockets,请安装 WebSockets 能力。

在 Agent 类上使用

Agent 类会调用相同的 onRequest(request) 方法,因此只需将这些示例中的 Lifecycle 配置替换为 extends Agent<Env>,即可在 Agent 上使用。

Streams

写入回复时将其存储,以便客户端可以恢复接收。

这篇文档对您有帮助吗?