Introducción a la ESS
SSE (Server-Sent Events, Server-Sent Events) es una API o patrón que gira en torno a las interacciones Comet de solo lectura.
La API de SSE permite que las páginas web obtengan actualizaciones del servidor y se usa para crear una conexión unidireccional con el servidor a través de la cual el servidor puede enviar cualquier cantidad de datos. El tipo MIME de la respuesta del servidor debe ser texto/flujo de eventos, y la API de JavaScript en el navegador puede analizar el formato de salida.
SSE admite encuestas cortas, encuestas largas y transmisión HTTP, y puede determinar automáticamente cuándo volver a conectarse si se desconecta.
motivo de uso
En el pasado, la información, como las notificaciones del sistema y los anuncios, se evaluaba llamando a la interfaz a intervalos regulares para determinar si había nuevos anuncios o notificaciones. Al principio, pensé en usar websocket, pero este escenario solo requiere que el servidor envíe mensajes a el cliente, así que decidí usarlo después de la discusión.
// 使用这个库可以添加的请求头(比如添加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连接~")
}
},
Después de llamar a createSSE, la solicitud siempre estará en estado pendiente
El estado no cambiará hasta que el servidor envíe un mensaje al cliente
Recuerda cerrar la conexión al salir al final