🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# **EventSource** ## **后端** #### **创建路由** ``` const express = require("express"); const router = express.Router(); router.get("/events", (req, res) => { res.setHeader("Content-Type", "text/event-stream"); res.setHeader("Cache-Control", "no-cache"); res.setHeader("Connection", "keep-alive"); res.flushHeaders(); const sendEvent = (data) => { res.write(`data: ${data}\n\n`); }; // 模拟每秒发送一个事件 setInterval(() => { const eventData = "This is an event." + new Date().toLocaleString(); sendEvent(eventData); }, 1000); // 监听前端主动发起关闭后回调 req.connection.addListener( "close", () => { console.log("SSE connection closed!"); }, false ); }); module.exports = router; ``` #### **添加到app.js中** ``` const EventSourceRouter = require("./routes/EventSourceRouter"); app.use(EventSourceRouter); ``` ## **前端** ``` <template> <div> {{ message }} <el-button size="default" v-if="ES" @click="close">断开</el-button> <el-button type="primary" size="default" v-else @click="init"> 链接 </el-button> </div> </template> <script setup> import { ElMessage } from "element-plus"; import { ref, onMounted, onUnmounted } from "vue"; const message = ref(""); const ES = ref(null); const init = () => { ES.value = new EventSource("/api/events"); ES.value.onmessage = (event) => { message.value = event.data; }; ES.value.onerror = (event) => { if (ES.value.readyState === EventSource.CLOSED) { console.log("Connection to server closed"); } else { console.error("EventSource failed:", event); } // 不再需要时,关闭连接 close(); }; ES.value.onopen = (event) => { ElMessage.success("链接成功"); }; }; const close = () => { ES.value.close(); ES.value = null; ElMessage.error("链接断开"); }; onMounted(() => { init(); }); onUnmounted(() => { close(); }); </script> <style lang="scss" scoped></style> ```