Skip to content

Cloudflare 持久对象

¥Cloudflare Durable Objects

Cloudflare Durable Objects 无法直接处理 HTTP 请求。它们通过两步流程工作:

¥Cloudflare Durable Objects cannot handle HTTP requests directly. Instead, they work through a two-step process:

  1. Worker 接收来自客户端的 HTTP 获取请求

    ¥A Worker receives HTTP fetch requests from clients

  2. Worker 向 Durable Object 发起 RPC(远程过程调用)调用

    ¥The Worker makes RPC (Remote Procedure Call) invocations to the Durable Object

  3. 持久对象处理 RPC 并将结果返回给 Worker。

    ¥The Durable Object processes the RPC and returns the result to the Worker

  4. Worker 将 HTTP 响应发送回客户端

    ¥The Worker sends the HTTP response back to the client

你可以在 Cloudflare Worker 中使用 Hono 作为路由,调用 RPC(远程过程调用)与 Durable Objects 进行交互。这是 Cloudflare Workers 兼容日期 2024-04-03 的推荐方法。

¥You can use Hono as the router in your Cloudflare Worker, calling RPCs (Remote Procedure Calls) to interact with Durable Objects. This is the recommended approach as of Cloudflare Workers compatibility date 2024-04-03.

示例:计数器持久对象

¥Example: Counter 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 app

wrangler.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,
  },
}

现在,你拥有一个功能齐全的 Hono 应用,它可以与你的 Durable Object 进行交互!Hono 路由提供了一个简洁的 API 接口,用于与你的持久对象的方法进行交互并公开这些方法。

¥Now you have a fully functional Hono application that interfaces with your Durable Object! The Hono router provides a clean API interface to interact with and expose your Durable Object's methods.

Hono v4.11 中文网 - 粤ICP备13048890号