在 Nuxt 上实现基于内存的消息广播

Feb 07, 2026 · 1395 字

如果需要在 Nuxt 上实现 Realtime 功能,通常需要使用 WebSocket 或者 Server-Sent Events 等技术来实现消息的实时传递。而由于 Serverless 平台对执行时间的限制(以及某些平台压根不支持 Stream),这种实时能力通常只能在 node-server 等持久运行的平台上实现。如果我们能进一步限制条件为仅在单实例上实现消息广播,那么就可以通过内存来实现消息的广播,而不需要依赖外部的消息队列或者数据库。

实际上,Nuxt 本身就有用到一定的内存广播机制,比如在开发模式下,Nuxt 会通过内存广播来通知所有实例进行热更新。我们可以借鉴这个机制来实现我们自己的消息广播。

要实现这个功能,我们需要使用 Nuxt 所基于的 Nitro 提供的 KV Storage 功能,默认情况下他是使用内存来存储数据的,并且提供了 watch 能够监听所有 KV 修改,所以我们可以直接这样实现一个简单的消息广播。

首先建立一个 API 来接收消息并存储到 KV 中:

export default defineEventHandler(async (event) => {
  const { id } = getRouterParams(event);
  const { msgId, msg } = await readBody(event);
  useStorage().setItem(`custom:${id}:${msgId}`, msg);
});

然后另外建立一个流式 API 来监听 KV 的变化并将消息广播出去:

export default defineEventHandler(async (event) => {
  const { id } = getRouterParams(event);
  const eventStream = createEventStream(event);
  const unwatch = await useStorage().watch((event, key) => {
    if (key?.startsWith(`custom:${id}:`)) {
      eventStream.push(
        JSON.stringify({ event, key, value: useStorage().getItem(key) }),
      );
    }
  });
  eventStream.onClosed(() => {
    unwatch();
    eventStream.close();
  });
  return await eventStream.send();
});

聪明的读者肯定想到了,如果我们直接将 driver 从内存切换到 redis,是不是就能实现多实例广播了?但是由于这个功能所基于的 unstorage 暂时并没有为 redis 实现 watch 能力,因此目前我们无法通过只修改 driver 的方式实现多实例广播。

目录

粤ICP备2025414119号 粤公网安备44030002006951号

© 2026 Saurlax · Powered by Astro