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
上一篇下一篇

猜你喜欢

热点阅读