sse和websocket有点类似,相比于传统的HTTP协议,他们的通信成本更低,可以建立长连接,实时性高,不必每次收发消息都要进行繁琐的握手挥手。而sse和websocket的区别在于,sse是单向的,只能服务器向客户端发送消息,而websocket是双向的。如果只是单纯实现一个消息推送,而不考虑什么已读未读之类的客户端返回数据,用SSE可能更好一些。
sse本身还是基于HTTP协议的,但是会在请求头中进行特殊的设置,告诉客户端接收的是SSE数据。
今天使用node.js的express框架搭一个后端服务器,客户端用vue搭一个。简单实现一下功能。
一、服务器
用的express框架,做的比较简单,创建一个server.js的文件即可

SSE和普通的HTTP协议的区别就在于响应头

因为前后的分离端口不同,所以最后一行要配置一下跨域
const express = require("express");
const app = express();
app.get("/sse", (req, res) => {
// 设置 SSE 相关的响应头
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
res.setHeader("Access-Control-Allow-Origin", "*"); // 允许跨域
let index = 0;
const timer = setInterval(() => {
res.write(`event:sseEvent\n`);
res.write(`id:${index}\n`);
res.write(`retry: 30000\n`);
res.write("data: " + JSON.stringify({ content: new Date() }) + "\n\n");
index++;
}, 2000);
// 当客户端点击关闭时
req.on("close", () => {
clearInterval(timer);
res.end();
});
});
app.listen(3000, () => {
console.log("服务开启成功");
});
这里的res.write(event:sseEvent\n)
不是随便写的,客户端的要和这里匹配。 打开控制台,输入node server,开启服务。

二、客户端
因为公司的node版本都比较老,所以简单创建了一个vue2项目。 url用你本地的地址,端口后端设的3000这里写3000就可以了。 addEventListener中监听的名字要和后端设置的相同。 按钮startConn事件记得检测之前是否有创立过连接,不然会创建很多个。
<template>
<div id="app">
<button @click="startConn">建立连接</button>
<button @click="endConn">关闭连接</button>
<div> {{ stateData }} </div>
<div>
<div v-for="(item, index) in list" :key="index"> {{ item }} </div>
</div>
</div>
</template>
<script>
export default {
name: "App",
components: {
// HelloWorld
},
data() {
return {
sse: null,
stateData: null,
list: [],
};
},
created() {},
methods: {
startConn() {
let url = "http://192.168.1.111:3000/sse";
const sse = new EventSource(url);
console.log(this.sse,'this.sse')
if(this.sse?.readyState==1){
console.log('已建立连接')
return
}
this.sse = sse;
sse.onopen = (e) => {
let data = `SSE 连接成功,状态${sse.readyState}`;
this.stateData = data;
console.log("open", e);
console.log(data, sse);
};
sse.addEventListener("sseEvent", (event) => {
const data = JSON.parse(event.data);
console.log(data, "data111111");
this.list.push(data.content);
console.log(event, "event");
});
sse.onerror = (e) => {
console.log("error", e);
};
},
endConn() {
this.sse.close();
console.log("end");
},
},
};
</script>
效果如下
