跳到主要内容
Deno KV watch

使用 Deno KV 中新的 “watch” API 构建实时应用程序

Deno KV,我们内置于运行时的 ACID 兼容键值数据库,是我们通过消除样板代码和配置来从根本上简化云开发的愿景迈出的重要一步。您只需一行代码即可连接到数据库,而无需处理 API 密钥和配置数据库

const kv = await Deno.openKv();
而且,如果您将其与 Deno Deploy 一起使用,您的数据可以在全球范围内复制并扩展,而无需任何进一步的设置。

我们继续为 Deno KV 推出大量功能,例如 开源的自托管服务器从 Deno Deploy 外部远程连接到托管 Deno KV 实例 的能力,以及 持续备份到对象存储。但今天,我们将推出一项新功能,它将简化构建一整类实时应用程序 - kv.watch

let seen = "";
for await (const [messageId] of kv.watch([["last_message_id", roomId]])) {
  const newMessages = await Array.fromAsync(kv.list({
    start: ["messages", roomId, seen, ""],
    end: ["messages", roomId, messageId, ""],
  });
  
  await websocket.write(JSON.stringify(newMessages));
  seen = messageId;
}
使用 `kv.watch` 的实时聊天应用程序。

kv.watchDeno 1.38.5Deno Deploy 中受支持,允许您监听 Deno KV 键的更改,从而简化构建

  • 实时 UI 更新,例如社交媒体新闻提要或通知
  • 聊天应用程序或聊天室,如 Slack 和 Discord
  • 协作编辑器,如 Google Docs

在这篇博文中,我们将介绍

在上面的 YouTube 视频中了解新的 watch 功能。

新的 .watch() 👀 函数

新的 .watch() 函数接受一个键数组,并返回一个 ReadableStream,每当监视的键更改其 versionstamp 时,它都会发出一个新值。

在下面的示例中,我们监视键 ["foo"]["bar"] 的更新

const db = await Deno.openKv();

const stream = db.watch([["foo"], ["bar"]]);
for await (const entries of stream) {
  entries[0].key; // ["foo"]
  entries[0].value; // "bar"
  entries[0].versionstamp; // "00000000000000010000"
  entries[1].key; // ["bar"]
  entries[1].value; // null
  entries[1].versionstamp; // null
}

请注意,在单个 kv.watch 调用中可以传递的最大键数为 10 个。

为了将 kv.watch 添加到站点或应用程序中,您需要将其与服务器端事件或 WebSocket 一起使用。

构建实时更新

为了获得更实际的示例,下面的代码使用 kv.watch 监听帖子评论和点赞数的更改,然后使用 服务器发送事件 将它们分发到客户端

import { Application, Router } from "https://deno.land/x/oak/mod.ts";

const app = new Application();
const router = new Router();

// Send server side event on every activity on this blog post.
router.get("/api/blog_post_updates", async (ctx) => {
  const target = ctx.sendEvents();
  const postId = ctx.url.searchParams.get("post_id");
  for await (
    const [{ value: lastCommentId }, { value: likeCount }] of kv.watch([
      ["lastCommentId", postId],
      ["likeCount", postId],
    ])
  ) {
    target.dispatchMessage({ lastCommentId, likeCount });
  }
});

app.use(router.routes());
await app.listen({ port: 80 });

客户端需要在端点 /api/blog_post_updates 创建连接。然后,客户端将收到包含新评论和点赞数的服务器端事件,它可以在 HTML 中呈现这些事件。然后,UI 将呈现更新,而无需重新加载页面。

在 Deno Deploy 上监视更新

Deno Deploy 上的 Deno KV 是一个用于可扩展、可靠且 ACID 兼容存储的一体化解决方案,具有构建现代应用程序所需的所有原语

无论 isolate 在哪个区域中运行,kv.watch 更改通知都会以最小的延迟传递到 isolate。借助我们构建在 FoundationDB 之上的 高性能事务处理架构kv.watch 可以扩展到数十万并发客户端。

定价

Deno Deploy 上 Deno KV 的定价没有变化。但是,每次从 kv.watchReadableStream 响应中返回条目时,都会将其视为“读取”。

更多用例和示例

为了提供更多关于使用 kv.watch 的示例,我们更新了我们的 Deno KV 展示应用程序以包含 KV watch

这些示例让您了解可以使用 Deno KV watch 构建的实时或多用户协作应用程序。

更多资源

下一步是什么

Deno KV 与其他云原语(如 Deno Queues 和 Deno Cron)一起内置于运行时中,这使您可以更快地构建,而无需担心配置、配置或扩展基础设施。Deno KV 的新 kv.watch 通过让您检测 Deno KV 的更改,进一步简化了实时应用程序的构建。

我们始终乐于接受反馈和功能请求!请随时加入我们不断壮大的 Discord在此处创建 issue

我们刚刚发布了 Deno Cron!🦕🕒

在几分钟内在 Deno Deploy 上创建计划作业。