赞
踩
将数据用流的方式返回给客户端,这种技术需求在传统的管理项目中不多见,但是在媒体或者有实时消息等功能上就会用到,这个知识点对于前端还是很重要的。
即时你不写服务端,但是服务端如果给你这样的接口,你也得知道怎么去使用联调。
SSE服务(Server-Sent Events),是一种服务器向客户端推送实时更新的机制模式。
- 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
- 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>
- <p v-for="(item,index) in msgList" :key="index">{{ item }}</p>
- </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">
- </style>
这样就大功告成了,如果以后要是做类似于chatgpt这种效果,就可以用到的。
感觉有用的给个三连吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。