sse实时通信

使用原因:用户网络环境较差,之前使用ws总是出现断连重连,导致数据总是不能实时更新,所以更换为sse

npm install event-source-polyfill

createWebSocket:创建sse连接 

getWebSocketMsg:接收sse消息

  import { EventSourcePolyfill } from "event-source-polyfill";
  import { getToken } from '@/utils/auth'
  class webSocketClass {
  constructor(name) {
    this.localUrl = `http`; //直连阿里云正式环境
    this.globalCallback = null;
    this.createWebSocket(name);
    this.readyState = 0;
  }
  createWebSocket(url) {
    var that =this
    // 建立连接
    this.eventSource = new EventSourcePolyfill(
      this.localUrl+ url,
      {
        // 设置重连时间
        heartbeatTimeout: 60 * 60 * 1000,
        // 添加token
        headers: {
          Authorization: `Bearer ${getToken()}`,
        },
      }
    );
    this.eventSource.onopen = (e) => {
      console.log("已建立SSE连接~");
    };
    this.eventSource.onmessage = (e) => {
      const d = JSON.parse(e.data);
      console.log("sse已接受到消息:", d);
      that.getWebSocketMsg(that.globalCallback);

    };
    this.eventSource.onerror = (e) => {
      console.log("SSE连接错误" + e.readyState);
      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);
      }
    };
  }
  getWebSocketMsg(callback) {
      console.log("开始接收sse消息~",this.eventSource);
      this.eventSource.onmessage = (ev) => {
        callback && callback(ev);
    };
  }
  close(){
      this.eventSource.close()
      console.log("SSE关闭" );
  }
}
export default webSocketClass;

使用方法:

  this.warningSSE = new vueSSEUtil('/sse/warning/'+this.userId);
  this.warningSSE.getWebSocketMsg((evt) => {
      const d = JSON.parse(evt.data);
      d.warnCode = this.code_to_value(d.warnCode);
      console.log('sse回调数据',d) 
   });
     

一定要在页面退出关闭sse

this.warningSSE.close()

### Server-Sent Events (SSE) 实时推送实现方式及示例 Server-Sent Events (SSE) 是一种轻量级的服务器向客户端单向推送实时数据的技术,HTML5 引入了这种技术以实现实时通信SSE 使用标准的 HTTP 协议进行通信,支持跨浏览器兼容性,并且比 WebSocket 更加简单和易于实现。 #### 1. SSE 的基本原理 SSE 基于 HTTP 长连接机制,服务器通过 `text/event-stream` MIME 类型向客户端发送事件流。每个事件由键值对组成,事件之间通过空行分隔。客户端通过 JavaScript 的 `EventSource` API 接收这些事件并处理[^3]。 #### 2. Spring Boot 中实现 SSE 示例 在 Spring Boot 中,可以通过 `SseEmitter` 类来实现 SSE 功能。以下是完整的实现步骤: ##### 2.1 添加依赖 在 `pom.xml` 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` ##### 2.2 创建控制器 创建一个控制器类来处理 SSE 请求: ```java import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; import java.time.LocalDateTime; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @RestController @RequestMapping("/sse") public class SseController { private final ExecutorService executorService = Executors.newFixedThreadPool(10); @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter stream() { SseEmitter emitter = new SseEmitter(); // 处理超时 emitter.onTimeout(() -> { System.out.println("Emitter timed out"); emitter.complete(); }); // 发送数据 executorService.submit(() -> { try { for (int i = 0; i < 10; i++) { emitter.send(String.format("Data %d at %s", i, LocalDateTime.now())); Thread.sleep(1000); } emitter.complete(); } catch (IOException | InterruptedException e) { emitter.completeWithError(e); } }); return emitter; } } ``` ##### 2.3 客户端接收事件 在前端页面中使用 `EventSource` API 来接收服务器推送的数据: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SSE Example</title> </head> <body> <h1>Server-Sent Events Example</h1> <ul id="event-list"></ul> <script> const eventSource = new EventSource('/sse/stream'); eventSource.onmessage = function(event) { const list = document.getElementById('event-list'); const item = document.createElement('li'); item.textContent = event.data; list.appendChild(item); }; eventSource.onerror = function(error) { console.error('EventSource failed:', error); }; </script> </body> </html> ``` #### 3. SSE 的关键点 - **MIME 类型**:SSE 使用 `text/event-stream` 作为 MIME 类型[^4]。 - **事件格式**:每个事件由键值对组成,常见的键包括 `data`、`event` 和 `id`。 - **长连接**:SSE 使用 HTTP 长连接机制,服务器可以持续向客户端发送数据。 - **超时处理**:`SseEmitter` 提供了超时处理方法,可以通过 `onTimeout` 注册回调函数[^4]。 ### 注意事项 - SSE 仅支持单向通信,即服务器向客户端推送数据。 - 如果需要双向通信,可以考虑使用 WebSocket 技术。 - 在高并发场景下,需注意服务器资源的消耗和优化。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值