前端处理流式数据(SSE服务)

CSDN 2024-08-07 09:03:01 阅读 65

前言

将数据用流的方式返回给客户端,这种技术需求在传统的管理项目中不多见,但是在媒体或者有实时消息等功能上就会用到,这个知识点对于前端还是很重要的。

即时你不写服务端,但是服务端如果给你这样的接口,你也得知道怎么去使用联调。

nodejs实现简单的SSE服务

SSE服务(Server-Sent Events),是一种服务器向客户端推送实时更新的机制模式。

<code>const express = require('express');

const app = express();

const port = 8002;

let strArr = [

'所有人,都得死!',

'犯我德邦者,虽远必诛!',

'吾所成之事,不可逆也!',

'一点寒芒先到,随后枪出如龙!',

'我的剑就是你的剑!',

'刀下生,刀下死!'

]

let setTask = null

app.get('/events', (req, res) => {

res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');

res.setHeader('Cache-Control', 'no-cache');

res.setHeader('Connection', 'keep-alive');

let num = 0

setTask = setInterval(()=>{

res.write(`data:${strArr[num]}\n\n`)

num++

if(num > 5){

res.write(`data:end\n\n`)

res.end()

// res.closed()

clearInterval(setTask)

setTask = null

}

},1000)

});

app.listen(port, () => {

console.log(`${port}端口已启动`);

});

效果如下

 前端实现接收数据流:

这里使用一个叫做EventSource的api去实现流式接口的调用和数据获取

配置代理(重要)

如果我们用vue,react等等框架开发时,需要在代理处做一些配置,确保数据会以流式的返回。如果不做这层代理的配置,那么你获取的数据就会是执行完所有的res.write,一次性的全部返回给前端,就不是我们想要的效果。

效果如下,在配置代理中将compress设置为false

<code> devServer:{

client:{

overlay:false

},

port:8080,

open:true,

compress:false, //流式数据返回的关键配置

proxy:{

'/server1':{

target:'http://localhost:3001',

ws:false,

changeOrigin:true,

pathRewrite:{

'^/server1':''

}

},

'/server2':{

target:'http://localhost:3002',

ws:false,

changeOrigin:true,

pathRewrite:{

'^/server2':''

}

},

'/sse':{

target:'http://localhost:8002',

ws:false,

changeOrigin:true,

pathRewrite:{

'^/sse':''

}

}

}

}

之前没有配置这里,导致数据一直是一次性返回的,困了我一会,后来查找原因,借鉴的这篇文章

fetchEventSource请求,数据没有流式输出_vue2 eventsource为什么没有流式输出-CSDN博客

前端实现接口调用

<template>

<div>

<el-button @click="sendMsg">发送消息</el-button>code>

<p v-for="(item,index) in msgList" :key="index">{ { item }}</p>code>

</div>

</template>

<script>

export default{

name:'admin',

data(){

return{

msgList:[]

}

},

methods:{

sendMsg(){

let vm = this

//方案1:EventSource

const eventSource = new EventSource('/sse/events');

//消息监听

eventSource.onmessage = function(event) {

console.log(eventSource,vm,'状态')

console.log(event.data); // 输出SSE发送的数据

if(event.data === 'end'){

eventSource.close()

}else{

vm.msgList.push(event.data)

}

};

//连接成功

eventSource.onopen = function(event){

}

//连接出错

eventSource.onerror = function(error) {

if (eventSource.readyState === EventSource.CLOSED) {

// 连接已关闭,可能需要重新连接

console.error('SSE连接已关闭:', error);

}

}

//方案2:xhr(不推荐)

// const xhr = new XMLHttpRequest();

// const url = '/sse/events';

// xhr.open('GET', url,true);

// xhr.setRequestHeader('Accept', 'text/event-stream');

// xhr.onload = (event)=>{

// if(xhr.status === 200){

// console.log(xhr.responseText,'onload',event)

// }

// }

// xhr.onreadystatechange = (event)=>{

// // if(xhr.status === 200){

// // console.log(xhr.responseText,'onreadystatechange',event)

// // }

// }

// xhr.onprogress = (event)=>{

// if(xhr.status === 200){

// console.log(xhr.responseText,'onreadystatechange',event)

// }

// }

// xhr.send()

}

}

}

</script>

<style lang="less">code>

</style>

 这样就大功告成了,如果以后要是做类似于chatgpt这种效果,就可以用到的。

感觉有用的给个三连吧!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。