能否在Deno Fresh框架中使用Server Side Events实现POST处理器?
在Deno Fresh的POST处理器中使用Server Side Events的方案
当然可以在Deno Fresh的POST处理器中实现Server Side Events(SSE),用来推送长时间运行进程的实时更新。不过需要手动构建流式响应,适配SSE的长连接特性,以下是具体实现思路和示例:
核心实现要点
- 手动返回
Response对象,配置SSE所需的HTTP头部 - 使用
ReadableStream流式发送事件数据,避免一次性返回全部响应 - 处理长时间进程的逐步输出,确保客户端能实时接收更新
示例代码
服务端POST处理器
// routes/api/long-task.ts import { Handlers } from "$fresh/server.ts"; export const handler: Handlers = { async POST(req) { // 解析客户端请求参数(按需处理) const taskData = await req.json(); // 创建可读流用于推送SSE事件 const stream = new ReadableStream({ async start(controller) { try { // 模拟分步骤执行的长时间任务 for (let i = 1; i <= 5; i++) { // 构造标准SSE事件格式:data: [内容]\n\n const eventData = `data: ${JSON.stringify({ progress: `${i * 20}%`, message: `完成步骤 ${i}` })}\n\n`; // 向客户端推送事件 controller.enqueue(new TextEncoder().encode(eventData)); // 模拟任务执行延迟 await new Promise(resolve => setTimeout(resolve, 1000)); } // 发送任务完成事件 controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify({ progress: "100%", message: "任务完成" })}\n\n`)); } catch (err) { // 发送错误事件 controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify({ error: err.message })}\n\n`)); } finally { // 关闭流释放资源 controller.close(); } } }); // 返回SSE响应,设置必要头部 return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive", "Access-Control-Allow-Origin": "*" // 跨域场景需要,根据实际情况调整 } }); } };
客户端接收逻辑
由于EventSource默认仅支持GET请求,POST场景下需要用fetch配合流式读取:
async function runLongTask() { const response = await fetch("/api/long-task", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ taskId: "123" }) }); if (!response.body) return; const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; // 解析SSE数据(可能包含多个事件块) const chunks = decoder.decode(value).split("\n\n"); chunks.forEach(chunk => { if (chunk.startsWith("data: ")) { const data = JSON.parse(chunk.slice(6)); console.log("收到更新:", data); // 这里可以添加UI更新逻辑 } }); } }
注意事项
- 长连接超时:确保Deno服务器配置允许长连接,可在启动Fresh时调整
keepalive_timeout参数 - 资源清理:长时间进程中断时,要及时关闭
ReadableStream的controller,避免内存泄漏 - 错误处理:客户端和服务端都要处理连接中断、进程失败等异常情况
- 跨域配置:如果客户端和服务端跨域,需要在响应头中设置正确的CORS规则
内容的提问来源于stack exchange,提问作者Norfeldt
相关产品推荐
相关产品推荐

