springboot(47) : 流式HTTP接口

注意:

  • @Async会使流式输出无效,  线程池也是, 必须使用本文中的创建线程方式, 其他的未试过
  • 实例化SseEmitter时参数为超时时间, 默认好像是30秒, 请求时间超过超时时间再发送消息就会报异常

 

Controller


import org.springframework.http.MediaType;
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.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executors;

@RestController
public class SseTestController {

    @RequestMapping(path = "/sse/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter api(String msg) {
        SseEmitter emitter = new SseEmitter(600000L);

        Executors.newSingleThreadExecutor().execute(() -> {
            try {
                sendTestMsg(emitter);
                emitter.complete();
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });

        // 返回Emitter给客户端
        return emitter;
    }

    public static void sendTestMsg(SseEmitter emitter) throws Exception {
        String str = "清明时节雨纷纷, 路上行人欲断魂, 借问酒家何处有, 牧童遥指杏花村。";
        for (String s : splitStringIntoChunks(str, 3)) {
            emitter.send(SseEmitter.event()
                    .data(s, MediaType.TEXT_PLAIN)
                    .id(UUID.randomUUID().toString())
                    .name("message"));
            Thread.sleep(100);
        }
        emitter.send(SseEmitter.event()
                .data("_THE_END_", MediaType.TEXT_PLAIN)
                .id(UUID.randomUUID().toString())
                .name("message"));
    }

    public static List splitStringIntoChunks(String str, int chunkSize) {
        List chunks = new ArrayList<>();

        // 遍历字符串,每次截取指定长度的子串
        for (int i = 0; i < str.length(); i += chunkSize) {
            // 计算截取终点,注意不要超过字符串本身的长度
            int endIndex = Math.min(i + chunkSize, str.length());
            // 截取子串并添加到列表中
            chunks.add(str.substring(i, endIndex));
        }

        return chunks;
    }
}

HTML




    SSE Example


SSE

你可能感兴趣的:(#,springboot,spring,boot,http,后端)