服务器发送事件 + Java 与 Spring MVC

Posted

技术标签:

【中文标题】服务器发送事件 + Java 与 Spring MVC【英文标题】:Server sent events + Java with Spring MVC 【发布时间】:2012-04-22 04:50:30 【问题描述】:

我目前遇到了与 SSE 和 Windows XP 相关的问题。下面的源代码目前在我尝试过的所有 Chrome 中都可以使用,除了 Windows XP 中的 Chrome(?)不知道为什么。这旨在用于用户必须使用 Chrome 的控制面板。也就是说,我不关心IE、Firefox等。

问题:服务器端事件在任何地方都有效 (Chrome),但在 Windows XP (Chrome) 中无效。 当我说它有效时,我的意思是调用了消息处理程序。

代码

javascript 代码

if (!!window.EventSource) 
   console.log("Event source available");
   var source = new EventSource('/admin/systemalert');

   source.addEventListener('message', function(e) 
        console.log(e.data);
   );

   source.addEventListener('open', function(e) 
        console.log("Connection was opened.");
   , false);

   source.addEventListener('error', function(e) 
        if (e.readyState == EventSource.CLOSED) 
            console.log("Connection was closed.");
         else 
            console.log(e.readyState);    <-- in windows XP it prints Error here
        
   , false);
 else 
        console.log("No SSE available");

服务器端代码

@Controller
@RequestMapping("/admin/**")
public class AdminController 

        @RequestMapping("systemalert")
        public @ResponseBody String sendMessage(HttpServletResponse response) 
                Random r = new Random();
                response.setContentType("text/event-stream");
                try 
                        Thread.sleep(10000);
                 catch (InterruptedException e) 
                        e.printStackTrace();
                   
                return "data:Testing 1,2,3" + r.nextInt() +"\n";
        


如代码中所述,console.log(e.readyState); 行在 Windows XP 中使用 Chrome 时打印“错误”。有任何想法吗?有人看到源代码有什么问题吗?

提前致谢。 奥古斯丁

【问题讨论】:

你确定你在XP上安装的Chrome版本和其他代码成功的版本是一样的吗? 如果删除 response.setContentType("text/event-stream"); 会发生什么?也许 XP 无法识别此内容类型? 如果我删除它,我得到 EventSource 的响应具有不是“text/event-stream”的 MIME 类型(“text/html”)。中止连接。 【参考方案1】:

对于遇到此问题的任何人,问题与数据后所需的新行有关。基本上,你需要两行而不是我使用的一行。这样它就可以在任何地方工作。

改变这个:

return "data:Testing 1,2,3" + r.nextInt() +"\n";

到这里:

return "data:Testing 1,2,3" + r.nextInt() +"\n\n";

解决问题..

【讨论】:

【参考方案2】:

请注意 Spring Framework 4.2+ 支持 natively SSE,而不是手动实现 SSE。请参阅 this sample SSE enabled controller 返回 SseEmitter。

【讨论】:

【参考方案3】:

好的,我在 php + HTML5 中创建了一个小例子。

你可以看看here。你会看到我有两个不同的按钮;第一个用于创建事件源,第二个用于断开连接。

代码直接打印到 firefox/chrome 控制台。正如您将看到的,消息处理程序在 firefox 中调用,而不是在 chrome 中调用。

到目前为止,这不适用于我测试的任何 chrome。

Firefox 输出示例:

Creating event source
Open
Id: 1334072077
Message: Se puede leer esto?
Origin: http://arancione-consulting.com
Closed
Open
Id: 1334072082
Message: Se puede leer esto?
Origin: http://arancione-consulting.com
Closed

Chrome 输出示例:

Creating event source
Open
Closed
Open
Closed

如果有人想知道,服务器端代码是:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // prevent caching of event data.
echo "id: " . time() . "\n";
echo "Event: time\n";
echo "data: Se puede leer esto?\n";
flush();
?>

有什么想法吗?

【讨论】:

以上是关于服务器发送事件 + Java 与 Spring MVC的主要内容,如果未能解决你的问题,请参考以下文章

Spring中的服务器发送事件客户端示例

spring cloud bus原理总结

服务器使用 Spring Boot 和 WebFlux 发送事件

Spring boot SSE(服务器发送事件):如何动态发送响应

Spring Webflux:将服务器发送事件推送给特定用户

Spring boot:SSE 服务器发送的事件不起作用