简介
Inngest Realtime 通过 Server-Sent Events 把运行中任务的日志和中间结果流到浏览器。配合 React hook,进度条和实时状态不用轮询就能搭。适合长 AI 生成任务、批处理、任何用户等待且需要看进度的场景。需要 Inngest Cloud + 任何支持 EventSource 的前端。装机时间 5 分钟。
从任务发布
import { inngest } from "./client";
export const generateReport = inngest.createFunction(
{ id: "generate-report" },
{ event: "report.requested" },
async ({ event, step, publish }) => {
await publish({ channel: `run.${event.data.runId}`, topic: "status",
data: { stage: "fetching", percent: 10 }});
const data = await step.run("fetch", () => fetchReportData(event.data));
await publish({ channel: `run.${event.data.runId}`, topic: "status",
data: { stage: "processing", percent: 50 }});
const report = await step.run("generate", () => generateReportPDF(data));
await publish({ channel: `run.${event.data.runId}`, topic: "status",
data: { stage: "done", percent: 100, url: report.url }});
return report;
},
);在 React 里订阅
import { useInngestSubscription } from "@inngest/realtime/hooks";
function ReportProgress({ runId }: { runId: string }) {
const { latest } = useInngestSubscription({
channel: `run.${runId}`,
topics: ["status"],
});
if (!latest) return <div>Starting…</div>;
return (
<div>
<p>{latest.data.stage}</p>
<Progress value={latest.data.percent} />
{latest.data.url && <a href={latest.data.url}>Download report</a>}
</div>
);
}订阅所有消息(历史)
const { messages } = useInngestSubscription({ channel, topics });
// messages 是按时间排好的数组,可以渲染成日志
return (
<ol>
{messages.map((m, i) => (
<li key={i}>{m.data.stage} ({m.data.percent}%)</li>
))}
</ol>
);鉴权(前端无密钥)
前端用从你服务器签发的短期订阅 token。Inngest 签名密钥永远不到浏览器。
FAQ
Q: Realtime 跟轮询啥区别? A: SSE 在消息发布时立即推送。轮询有延迟(轮询间隔)和负载(每次都发请求)。Realtime 是一个持久连接,亚秒级更新。
Q: 浏览器之外能用 Realtime 吗? A: 能 —— 任何支持 SSE 的 HTTP 客户端都行。React hook 是可选的便捷封装,Vue / Svelte / 原生 JS / 服务端 EventSource 都能订阅。
Q: 免费档包含吗? A: 包含 —— Realtime 在所有 Inngest Cloud 档(含免费档)都可用。自托管 Inngest 也通过同 API 支持 Realtime。