SpringBoot项目整合SSE,实现服务端向前端页面推送数据

SpringBoot项目整合SSE,实现服务端向前端页面推送数据

  • 无需引入额外依赖
package cn.zm.ecp.module.es.controller.admin;

import jakarta.annotation.security.PermitAll;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * SSE测试
 */
@Slf4j
@RestController
@RequestMapping("/stream-sse")
public class SseController {

    private final AtomicInteger counter = new AtomicInteger(0);

    // 模拟获取历史数据
    private List getHistoricalData() {
        List historicalData = new ArrayList<>();
        try {
            for (int i = 0; i < 5; i++) {
                String time = LocalDateTime.now().minusMinutes(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                historicalData.add("Historical Data: " + i + ", Time: " + time);
            }
        } catch (Exception e) {
            // 记录日志或进行其他处理
            log.error("获取历史数据时出现异常: " + e.getMessage());
        }
        return historicalData;
    }

    @GetMapping(path = "/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @PermitAll
    public Flux> streamSseMvc() {
        // 先发送历史数据
        Flux> historicalFlux = Flux.fromIterable(getHistoricalData())
                .map(data -> ServerSentEvent.builder()
                        .data(data)
                        .build())
                .onErrorResume(error -> {
                    log.error("发送历史数据时出现异常: " + error.getMessage());
                    return Flux.empty();
                });

        // 再发送实时数据
        Flux> realTimeFlux = Flux.interval(Duration.ofSeconds(5))
                .map(seq -> {
                    try {
                        // 模拟获取实时数据
                        int data = counter.incrementAndGet();
                        // 获取当前时间
                        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                        // 组合实时数据和时间
                        String message = "Real-time Data: " + data + ", Time: " + currentTime;
                        return ServerSentEvent.builder()
                                .data(message)
                                .build();
                    } catch (Exception e) {
                        log.error("发送实时数据时出现异常: " + e.getMessage());
                        return ServerSentEvent.builder()
                                .data("Error occurred while sending data")
                                .build();
                    }
                });

        // 合并历史数据和实时数据
        return Flux.concat(historicalFlux, realTimeFlux);
    }
}    

你可能感兴趣的:(Java,spring,boot,前端,后端)