H1-H10 优化OCR实时体验闭环
这个提交包含在:
@@ -0,0 +1,52 @@
|
||||
const { canReceiveEvent, toClientEvent } = require("../services/events");
|
||||
|
||||
const HEARTBEAT_INTERVAL_MS = 25_000;
|
||||
|
||||
function writeSseEvent(raw, event) {
|
||||
const clientEvent = toClientEvent(event);
|
||||
if (!clientEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
raw.write(`id: ${clientEvent.id}\n`);
|
||||
raw.write(`event: ${clientEvent.type}\n`);
|
||||
raw.write(`data: ${JSON.stringify(clientEvent)}\n\n`);
|
||||
}
|
||||
|
||||
async function eventsRoutes(fastify) {
|
||||
fastify.get(
|
||||
"/events",
|
||||
{
|
||||
preHandler: fastify.authenticate,
|
||||
},
|
||||
async (request, reply) => {
|
||||
const canManageInvoice = fastify.hasPermission(request.employee, "invoice.manage");
|
||||
reply.hijack();
|
||||
reply.raw.writeHead(200, {
|
||||
"content-type": "text/event-stream; charset=utf-8",
|
||||
"cache-control": "no-cache, no-transform",
|
||||
"connection": "keep-alive",
|
||||
"x-accel-buffering": "no",
|
||||
});
|
||||
reply.raw.write(": connected\n\n");
|
||||
|
||||
const unsubscribe = fastify.appEvents.subscribe((event) => {
|
||||
if (!canReceiveEvent(request.employee, event, { canManageInvoice })) {
|
||||
return;
|
||||
}
|
||||
writeSseEvent(reply.raw, event);
|
||||
});
|
||||
|
||||
const heartbeat = setInterval(() => {
|
||||
reply.raw.write(": heartbeat\n\n");
|
||||
}, HEARTBEAT_INTERVAL_MS);
|
||||
|
||||
request.raw.on("close", () => {
|
||||
clearInterval(heartbeat);
|
||||
unsubscribe();
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = eventsRoutes;
|
||||
在新工单中引用
屏蔽一个用户