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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10079573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 08:37:32  来源:igfitidea点击:

Server sent events + Java with Spring MVC

javajavascripthtmlspring-mvc

提问by Agustin Lopez

I am currently having a problem related to SSE and Windows XP. The source code below is currently working in every Chrome I tried except for Chrome in Windows XP (?) Not sure why. This is intended to be used for a control panel, where users mustuse Chrome. In other words, I don't care about IE, Firefox, etc.

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

The problem: Server side events works everywhere (Chrome) but not in Windows XP (Chrome). When I say it works, I mean that the message handler is called.

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

The code

代码

  • Javascript code

    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");
    }
    
  • Server side code

    @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";
            }
    
    }
    
  • 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";
            }
    
    }
    

As stated in the code, the line console.log(e.readyState); prints "Error" when using Chrome in Windows XP. Any ideas? Anyone see anything wrong with the source code?

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

Thanks in advance. Agustin

提前致谢。奥古斯丁

采纳答案by Agustin Lopez

For anyone with this problem, the problem was related to the new lines needed after the data. Basically, you need two lines and not one as I was using. That way it works everywhere.

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

Changing this:

改变这一点:

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

To this:

对此:

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

Fixes the problem..

解决问题..

回答by Sébastien Deleuze

Instead of implementing manually SSE, be aware that Spring Framework 4.2+ supports natively SSE. See this sample SSE enabled controllerreturning an SseEmitter.

请注意 Spring Framework 4.2+本身支持 SSE,而不是手动实现SSE。请参阅此示例 SSE 启用控制器返回SseEmitter

回答by Agustin Lopez

Ok, I have created a small example in PHP + HTML5.

好的,我已经用 PHP + HTML5 创建了一个小例子。

You can take a look at it here. You will see that I have two different buttons; one to create the event source and the second one to disconnect it.

您可以在此处查看。你会看到我有两个不同的按钮;第一个创建事件源,第二个断开它。

The code prints directly to firefox/chrome console. As you will see, the message handler is called in firefox but not chrome.

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

This is not working on any chrome I tested so far.

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

Example Firefox output:

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

Example Chrome output:

Chrome 输出示例:

Creating event source
Open
Closed
Open
Closed

In case anyone wants to know, the server side code is:

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

<?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();
?>

Any ideas?

有任何想法吗?