EventSource 长链接执行

EventSource 说明文档MDN
其他参考文档

一、利用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、