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

SSE无法触发onmessage问题求助(Java Servlet + ES6 JS)

我帮你定位到问题啦!你的SSE连接能正常建立,但客户端onmessage收不到数据,核心原因是服务端输出的SSE消息格式不符合标准规范,浏览器无法识别这些内容为有效的SSE消息。

SSE消息的强制格式要求

SSE协议对服务端输出的消息有严格格式规定,必须满足:

  • 每条消息必须以data:前缀开头
  • 消息内容结束后必须跟上两个换行符(\n\n),用来标记当前消息结束
  • 如果消息内容是多行文本,每行都需要单独以data:开头,最后再用\n\n收尾

你的服务端代码里直接输出了"Rnd: " + rnd,完全没有遵循这个格式,所以浏览器接收到数据后,不会触发onmessage回调。

修改后的服务端代码

把服务端的输出语句调整为符合SSE格式的写法,同时建议加上缓存控制头避免浏览器缓存:

response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
// 禁止缓存SSE响应,避免浏览器复用旧连接
response.setHeader("Cache-Control", "no-cache");
PrintWriter printWriter = null;
try {
    printWriter = response.getWriter();
    while(true) {
        double rnd = Math.random() * 10000;
        // 按照SSE格式输出消息:data: 内容 + 两个换行符
        printWriter.print("data: Rnd: " + rnd + "\n\n");
        response.flushBuffer();
        Thread.sleep(5000);
    }
} catch(IOException | InterruptedException e) {
    e.printStackTrace();
} finally {
    // 确保PrintWriter不为null时再关闭
    if(printWriter != null) {
        printWriter.close();
    }
}

额外注意事项

  • 我把循环和资源初始化的位置调整了一下,避免每次循环都获取PrintWriter,更高效也更安全
  • 异常处理改用finally块来关闭资源,防止出现空指针异常
  • 加上Cache-Control: no-cache头,避免某些浏览器缓存SSE连接的响应内容,导致后续消息无法正常接收

修改完服务端代码后,重启Payara服务器,再测试客户端,你应该就能看到onmessage正常接收随机数消息了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:48:20