EventSource案例
2024-04-17 本文已影响0人
姜治宇
什么是EventSource?
EventSource 是 HTML5 中引入的一个 API,用于从服务器接收服务器发送事件(Server-Sent Events,SSE)。通过 EventSource,浏览器可以建立一个到服务器的单向连接,服务器可以随时向客户端发送消息。这种方式通常用于实时数据推送,如股票行情、新闻更新等场景。
与轮询的区别
SSE 通常比轮询更高效,因为它维护一个单一的持久连接,并且只在有新数据时发送更新,而轮询可能会导致服务器和客户端的资源消耗较高,因为它需要频繁地建立和关闭连接。
与websocket的区别
SSE是单向通信,只是http服务器单向往客户端发送消息,适用于消息推送场景,比如股市走势;而websocket则是双向的,不仅服务器可以往客户端发送消息,客户端也可以往服务端发送消息,也就是全双工通信,适用于聊天、游戏等场景。
示例
还是以nestjs为例。
app.controller.ts:
import { Controller, Get, Param,Res } from '@nestjs/common';
import { AppService } from './app.service';
import { Response } from 'express';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('event-stream/:phone')
evtSource(@Param('phone') phone: any,@Res() res: Response) {
res.writeHead(200, {
'Content-Type': 'text/event-stream;charset=utf-8',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
});
const intervalId = setInterval(async () => {
const obj = {
code: 0,
success: true,
phone: phone,
time: new Date().toISOString(),
};
const eventData = 'data:' + JSON.stringify(obj) + '\n\n'; //数据返回的格式需要注意一下
res.write(eventData);
}, 2000); // 每2秒发送一个事件
res.on('close', () => {
clearInterval(intervalId);
});
}
}
sse是长连接,所以首先需在头部声明一下这是长连接,而且没有缓存。
res.writeHead(200, {
'Content-Type': 'text/event-stream;charset=utf-8',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
});
然后要注意返回的数据格式。必须是字符串,而且是"data: xxxx \n\n"这样的形式,否则在前端捕获不到数据。
前端 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test eventsource</title>
</head>
<body>
<div id="cont">
</div>
</body>
</html>
<script>
const eventSource = new EventSource('http://localhost:3003/event-stream/19612345678');
const cont = document.getElementById('cont');
eventSource.onmessage = (event) => {
const result = JSON.parse(event.data);
cont.innerText = '手机号:' + result.phone + '日期:' + result.time;
};
</script>
5.png