Cloudflare Durable Objects
Cloudflare Durable Objects 无法直接处理 HTTP 请求,而是通过以下两个阶段完成处理:
- Worker 接收客户端的 HTTP fetch 请求
- Worker 向 Durable Object 发起 RPC(远程过程调用)
- Durable Object 处理 RPC,并将结果返回给 Worker
- Worker 将 HTTP 响应返回给客户端
可以在 Cloudflare Worker 中使用 Hono 作为路由器,通过 RPC(远程过程调用)与 Durable Objects 交互。自 Cloudflare Workers 兼容性日期 2024-04-03 起,这是推荐的方式。
示例:计数器 Durable Object
ts
import { DurableObject } from 'cloudflare:workers'
import { Hono } from 'hono'
export class Counter extends DurableObject {
// In-memory state
value = 0
constructor(ctx: DurableObjectState, env: unknown) {
super(ctx, env)
// `blockConcurrencyWhile()` ensures no requests are delivered until initialization completes.
ctx.blockConcurrencyWhile(async () => {
// After initialization, future reads do not need to access storage.
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
}
}
// Create a new Hono app to handle incoming HTTP requests
type Bindings = {
COUNTER: DurableObjectNamespace<Counter>
}
const app = new Hono<{ Bindings: Bindings }>()
// Add routes to interact with the 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())
})
// Export the Hono app as the Worker's fetch handler
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 的方法。