EventSource 长链接执行
一、利用node启服务
import fs from 'fs'
import express from 'express'
const app = express()
// eventSource 仅支持 get 方法
// 服务器端发送的数据必须是纯文本格式,不能是二进制数据。
app.get('/api', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Connection': 'close',
'Access-Control-Allow-Origin': 'http://127.0.0.1:5172', // vue 项目启的服务,允许跨域ip
'Access-Control-Allow-Credentials': 'true',
})
const data = fs.readFileSync('./src/service/index.text', 'utf8')
console.log('=data===', data)
const total = data.length
let current = 0
// 定时器模拟持续发送消息,如果消息流一但断开就不会重新链接
let time = setInterval(() => {
console.log(current, total)
if (current >= total) {
console.log('end')
clearInterval(time)
return
}
// 返回自定义事件名
// res.write(`event:lol\n`)
// 返回数据
// res.write(`data:${data.split('')[current]}\n\n`)
/**
* 自定义事件需要 如:event:事件名\n 格式
* 写入数据 需要 如:data:流\n\n 格式,注意是两个 \n
* 写入的 流 最好是JSON 类型的字符串,因如果读取的内容中有 \r 或者 \n 时候会导致 后面的内容无法写入;
* */
res.write(`data:${JSON.stringify({data: data})}\n\n`)
current++
}, 300)
})
app.listen(3000, () => {
console.log('listen on port 3000')
})
特别说明:
1、服务端 需要设置 ‘Content-Type’: ‘text/event-stream’
2、如果是vue 项目需要自己补充允许跨域的 ip 或域名,否则前端调用会跨域
3、eventSource:仅支持 get方法,且服务端发送的是纯文本,不能是二进制流(会耗费大量内存,得不偿失)
4、node express 其他内容参考如下:express官网
二、前端vue 项目
文件路径如下:
如启动node 服务:node ./src/service/nodeService.js
启动vue 项目 自行 看package.json
<template>
<div>This is a EventSource dome</div>
</template>
<script setup>
import { onMounted } from 'vue'
const connectEventSource = () => {
const sse = new EventSource('http://127.0.0.1:3000/api')
sse.addEventListener('message', (mes) => {
// 服务端未自定义事件时候,默认走message
console.log('==message==', mes, mes.data ? JSON.parse(mes.data).data : '5555'
)
})
sse.addEventListener('open', (e) => {
console.log('===,', e)
})
//对应后端nodejs自定义的事件名lol;有此自定义事件名时候,不会走message
sse.addEventListener('lol', (e) => {
console.log('---lol-',e)
})
}
onMounted(() => {
connectEventSource()
})
</script>
注意事项
1、前端需要再 proxy 中配置跨域代理服务信息
如:
server: {
origin: `http://localhost:${PORT}`,
host: 'localhost',
port: PORT,
strictPort: true, // 设为 true 时若端口已被占用则会直接退出,而不是尝试下一个可用端口。
open: true,
proxy: {
'/api/': {
target: 'http://127.0.0.1:3000',
changeOrigin: true,
rewrite:(path) => path.replace(RegExp(`^api`), '/api')
}
}
},
2、