You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

StreamingResponseBody在WebSocket连接中失效,能否用于该场景?

能否在WebSocket连接中使用StreamingResponseBody?

结论:不能直接使用StreamingResponseBody实现WebSocket流式视频传输,二者的设计场景和技术模型完全不兼容,以下是具体分析和解决方案:

为什么你的代码无法运行?

  1. StreamingResponseBody的定位:它是Spring MVC专为HTTP请求-响应模型设计的组件,依赖Servlet容器的输出流来实现HTTP响应的流式输出,完全不支持WebSocket协议的消息模型。
  2. Spring WebSocket的处理逻辑:你用@MessageMapping+@SendTo的STOMP消息处理方式时,框架会尝试把返回的对象序列化为JSON/文本消息,而StreamingResponseBody不是可序列化对象,框架根本不会调用它的writeTo方法——这就是你看不到日志输出的原因。

正确的WebSocket流式视频实现方案

方案1:基于STOMP消息分块发送(适配你的现有代码结构)

将视频文件拆分成二进制块,通过SimpMessagingTemplate逐个发送到前端,前端收集后拼接播放:

@Controller
@Slf4j
public class RoomController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @MessageMapping("/message")
    public void streamVideo() throws IOException {
        Path videoPath = Paths.get("F:\\earth.mp4");
        // 用try-with-resources自动关闭流
        try (InputStream videoInputStream = Files.newInputStream(videoPath)) {
            byte[] buffer = new byte[4096]; // 增大缓冲区提升传输效率
            int bytesRead;
            while ((bytesRead = videoInputStream.read(buffer)) != -1) {
                // 发送切割后的二进制数据块
                messagingTemplate.convertAndSend("/topic/data", Arrays.copyOf(buffer, bytesRead));
                // 可选:添加小延迟避免前端消息积压
                Thread.sleep(10);
            }
            // 发送流结束标记,让前端停止收集数据
            messagingTemplate.convertAndSend("/topic/data", "STREAM_COMPLETE");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("视频流传输被中断", e);
        }
    }
}

前端需要监听/topic/data主题,收集二进制数据,收到结束标记后将数据转为Blob并生成视频URL播放。

方案2:原生WebSocket直接操作会话输出流

如果不需要STOMP协议的封装,可直接使用@ServerEndpoint实现原生WebSocket,通过会话的输出流直接传输视频数据:

@ServerEndpoint("/video-stream")
@Slf4j
public class VideoWebSocketEndpoint {

    @OnMessage
    public void startStreaming(Session session) throws IOException {
        Path videoPath = Paths.get("F:\\earth.mp4");
        try (InputStream is = Files.newInputStream(videoPath);
             OutputStream os = session.getBasicRemote().getSendStream()) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
                os.flush();
                Thread.sleep(15);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("视频流传输中断", e);
        }
    }
}

关键总结

  • StreamingResponseBody仅适用于HTTP响应的流式输出,和WebSocket的双向消息模型完全不兼容;
  • WebSocket流式传输的核心是分块发送二进制消息,或直接操作WebSocket会话的输出流;
  • 前端需要配合实现数据拼接、播放逻辑,注意处理消息积压和流结束的边界情况。

内容的提问来源于stack exchange,提问作者imakhlaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:47:20