SSE简介
SSE(Server-Sent Events,服务器发送事件)是围绕只读***et 交互推出的API 或者模式。
SSE API允许网页获得来自服务器的更新,用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的MIME类型必须是text/event-stream,而且是浏览器中的javascript API 能解析格式输出。
SSE 支持短轮询、长轮询和HTTP 流,而且能在断开连接时自动确定何时重新连接。
使用原因
之前系统通知公告等信息是通过每隔一段时间调用接口来判断是否有新的公告或通知,最开始想到的是用websocket,但是这场景只需要服务端往客户端发送消息,所以商量后决定使用SSE。
// 使用这个库可以添加的请求头(比如添加token)
import { EventSourcePolyfill } from "event-source-polyfill";
import { getToken } from '@/utils/user'
export default {
data() {
return {
eventSource: null
}
},
mounted() {
this.createSSE()
},
methods: {
createSSE(){
if(window.EventSource){
// 根据环境的不同,变更url
const url = process.env.VUE_APP_MSG_SERVER_URL
// 用户userId
const { userId } = this.$store.state.user
this.eventSource = new EventSourcePolyfill(
`${url}/sse/connect/${userId}`, {
// 设置重连时间
heartbeatTimeout: 60 * 60 * 1000,
// 添加token
headers: {
'Authorization': `Bearer ${getToken()}`,
},
});
this.eventSource.onopen = (e) => {
console.log("已建立SSE连接~")
}
this.eventSource.onmessage = (e) => {
console.log("已接受到消息:", e.data)
}
this.eventSource.onerror = (e) => {
if (e.readyState == EventSource.CLOSED) {
console.log("SSE连接关闭");
} else if (this.eventSource.readyState == EventSource.CONNECTING) {
console.log("SSE正在重连");
//重新设置token
this.eventSource.headers = {
'Authorization': `Bearer ${getToken()}`
};
} else {
console.log('error', e);
}
};
} else {
console.log("你的浏览器不支持SSE~")
}
},
beforeDestroy() {
if(this.eventSource){
const { userId } = this.$store.state.user
// 关闭SSE
this.eventSource.close();
// 通知后端关闭连接
this.$API.system.msg.closeSse(userId)
this.eventSource = null
console.log("退出登录或关闭浏览器,关闭SSE连接~")
}
},
在createSSE被调用后,这个请求会一直在pending状态
直到服务端向客户端发送消息,状态才会改变
最后离开时记得关闭连接