ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

html5-Spring SSEEmitter中途完成

2019-11-18 22:20:16  阅读:567  来源: 互联网

标签:server-sent-events html5 spring spring-mvc


我是服务器发送事件的新手,但不是Spring的新手.
已经制作了一个控制器,该控制器从启动SSEEmitter的UI上的按钮触发,并将其传递给另一个线程,该线程在每4秒后循环向UI发送消息.
到目前为止,我正在运行10个循环,每个循环睡眠4秒,但突然在第6或第7个循环的迭代附近,出现异常“线程“ Thread-4”中的异常java.lang.IllegalStateException:ResponseBodyEmitter已设置为完成”. .

因此,事件源再次重新建立连接,即再次调用控制器方法,这当然是我所不希望的.

我在这里尝试一件简单的事情.用户通过单击按钮进行订阅.
服务器无论何时都向浏览器发送响应10或20.就我而言,这就是上证所为之创造的.

代码如下:

@RequestMapping("/subscribe")
public SseEmitter subscribe() {
    SseEmitter sseEmitter = new SseEmitter();
    try {
        sseEmitter.send("Dapinder");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Runnable r = new AnotherThread(sseEmitter);
    new Thread(r).start();
    return sseEmitter;
}

公共类AnotherThread实现Runnable {

private SseEmitter sseEmitter;

public AnotherThread(SseEmitter sseEmitter) {
    super();
    this.sseEmitter = sseEmitter;
}

@Override
public void run() {
    SseEventBuilder builder = SseEmitter.event();
    builder.name("dapEvent");
    for (int i = 0; i < 10; i++) {
        builder.data("This is the data: " + i +" time.");
        try {
            //sseEmitter.send(builder);
            sseEmitter.send("Data: "+i);
            //sseEmitters.get(1L).send("Hello");
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    sseEmitter.complete();
}

public SseEmitter getSseEmitter() {
    return sseEmitter;
}

public void setSseEmitter(SseEmitter sseEmitter) {
    this.sseEmitter = sseEmitter;
}

}

function start() {
    var eventSource = new EventSource("http://localhost:8080/HTML5SSE/springSSE/subscribe"); //  /springSSE/connect
      eventSource.onmessage = function(event) {
        document.getElementById('foo').innerHTML = event.data;
    };

}


<button onclick="start()">Subscribe</button>

解决方法:

您的构建器未被使用;您创建并配置了构建器,但是随后直接使用“ sseEmitter.send”发送了一条简单消息.尝试这个:

sseEmitter.send(SseEmitter.event().name("dapEvent").data("This " + i +" time.");

还有一件事:为什么在subscribe方法中已经调用了send方法?此时,尚未返回SseEmitter.此消息是否传递给客户端?

这是一个excellent article,从JavaScript角度(不是Spring)说明了SSE.您将在此处看到可以通过调用流上的close从客户端取消事件流.将此与事件侦听器结合使用,您应该拥有所需的内容:

var source = new EventSource('...');
source.addEventListener('error', function(e) {
  if (e.currentTarget.readyState == EventSource.CLOSED) {
    // Connection was closed.
  } else {
    // Close it yourself
    source.close();
  }
});
source.addEventListener('message', function(e) {
  console.log(e.data);
});

注意:文章说e.readyState,但是我认为这是错误的.接收到的对象e是事件.您需要像这样从其中获取EventSource对象:e.currentTarget.

标签:server-sent-events,html5,spring,spring-mvc
来源: https://codeday.me/bug/20191118/2031475.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有