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
相关产品推荐
相关产品推荐

