fkc
Version:
FKC application service framework.
74 lines • 2.55 kB
JavaScript
;
module.exports = (req, res) => {
let heart = null;
const ok = ()=>{
return req.fkc.sse;
}
const clean = () => {
if(heart) {
// 清除心跳定时器
clearInterval(heart);
heart = null;
}
req.fkc.sse = false;
req.off('close', clean); // 移除close事件监听
req.off('error', clean); // 移除error事件监听
};
const write = (data)=>{
if(!req.fkc.sse) return;
try {
res.write(data);
} catch (e) {
clean();
}
};
const close = () => {
clean();
try {
res.end();
} catch (e) {
// 忽略结束时的错误
}
};
const open = (time = 30)=>{
if (req.fkc.sse) return;
try {
req.fkc.sse = true;
res.writeHead(200, {
'Content-Type': 'text/event-stream', // 声明是SSE流
'Cache-Control': 'no-cache', // 禁止浏览器缓存,实时推送
'Connection': 'keep-alive', // 保持HTTP长连接
'X-Accel-Buffering': 'no' // 禁止nginx缓存,流式输出必备
});
time = Math.max(time, 1) * 1000; // 至少1秒
heart = setInterval(() => {
// 心跳保活:30秒发送一次,防止连接超时断开(SSE规范心跳格式,浏览器不触发message事件)
write(`: ping\n\n`);
}, time);
return true;
} catch (error) {
close();
return false;
}
}
// ========== 2. 向当前客户端推送【普通消息】 ==========
const send = (data) => {
const sendData = typeof data === 'string' ? data : JSON.stringify(data);
write(`data: ${sendData}\n\n`); // SSE标准格式:data: 内容 + 两个换行结束
};
// ========== 3. 向当前客户端推送【自定义事件消息】 ==========
const sends = (eventName, data) => {
const sendData = typeof data === 'string' ? data : JSON.stringify(data);
write(`event: ${eventName}\ndata: ${sendData}\n\n`);
};
// ========== 4. 关闭当前SSE连接 ==========
req.on('close', clean); // 客户端主动断开
req.on('error', clean); // 请求异常
return {
ok,
open,
send,
sends,
close
};
};