Cloudflare Durable Objects
Cloudflare Durable Objects 不能直接处理 HTTP 请求,而是通过两步流程工作:
- A Worker receives HTTP fetch requests from clients
- Worker 向 Durable Object 发起 RPC(远程过程调用)
- Durable Object 处理 RPC 并将结果返回给 Worker
- Worker 再将 HTTP 响应发回客户端
你可以在 Cloudflare Worker 中将 Hono 作为路由器,并通过 RPC(远程过程调用)与 Durable Objects 交互。这是 Cloudflare Workers 兼容日期 2024-04-03 之后推荐的做法。
示例:Counter Durable Object
ts
import { DurableObject } from 'cloudflare:workers'
import { Hono } from 'hono'
export class Counter extends DurableObject {
// 内存状态
value = 0
constructor(ctx: DurableObjectState, env: unknown) {
super(ctx, env)
// `blockConcurrencyWhile()` 可确保在初始化完成前不会接收请求。
ctx.blockConcurrencyWhile(async () => {
// 初始化完成后,后续读取就不需要访问存储了。
this.value = (await ctx.storage.get('value')) || 0
})
}
async getCounterValue() {
return this.value
}
async increment(amount = 1): Promise<number> {
this.value += amount
await this.ctx.storage.put('value', this.value)
return this.value
}
async decrement(amount = 1): Promise<number> {
this.value -= amount
await this.ctx.storage.put('value', this.value)
return this.value
}
}
// 创建一个新的 Hono 应用来处理进入的 HTTP 请求
type Bindings = {
COUNTER: DurableObjectNamespace<Counter>
}
const app = new Hono<{ Bindings: Bindings }>()
// 添加与 Durable Object 交互的路由
app.get('/counter', async (c) => {
const env = c.env
const id = env.COUNTER.idFromName('counter')
const stub = env.COUNTER.get(id)
const counterValue = await stub.getCounterValue()
return c.text(counterValue.toString())
})
app.post('/counter/increment', async (c) => {
const env = c.env
const id = env.COUNTER.idFromName('counter')
const stub = env.COUNTER.get(id)
const value = await stub.increment()
return c.text(value.toString())
})
app.post('/counter/decrement', async (c) => {
const env = c.env
const id = env.COUNTER.idFromName('counter')
const stub = env.COUNTER.get(id)
const value = await stub.decrement()
return c.text(value.toString())
})
// 将 Hono 应用导出为 Worker 的 fetch 处理器
export default appwrangler.jsonc:
jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "durable",
"main": "src/index.ts",
"compatibility_date": "2025-04-14",
"migrations": [
{
"new_sqlite_classes": ["Counter"],
"tag": "v1",
},
],
"durable_objects": {
"bindings": [
{
"class_name": "Counter",
"name": "COUNTER",
},
],
},
"observability": {
"enabled": true,
},
}现在你已经拥有了一个可以与 Durable Object 交互的完整 Hono 应用了!Hono 路由器提供了简洁的 API 接口,用于访问并暴露 Durable Object 的方法。