改变这一行
writer.write("data: "+ i +"\n\n");
至
writer.write("data: "+ i +"\r\n");
顺便说一下,你的代码会有一个严重的性能问题,因为它会保留一个线程直到发送所有事件.请改用异步处理API.例如
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext actx = req.startAsync();
actx.setTimeout(30*1000);
//save actx and use it when we need sent data to the client.
}
然后我们可以稍后使用AsyncContext
//write some data to client when a certain event happens
actx.getResponse().getWriter().write("data: " + mydata + "\r\n");
actx.getResponse().getWriter().flush();
如果发送了所有事件,我们可以关闭它
actx.complete();
更新1:
如果我们不希望浏览器在服务器完成响应时再次重新连接服务器,我们需要在浏览器中关闭事件源.
eventSource.close();
另一种方法可能有帮助,即.我们设置了一个相当大的重试时间,但我没有尝试过,例如
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext actx = req.startAsync();
actx.getResponse().getWriter().write("retry: 36000000000\r\n"); // 10000 hours!
actx.getResponse().getWriter().flush();
//save actx and use it when we need sent data to the client.
}
更新2:
我认为Websocket对你的情况可能更好.
更新3 :(回答问题)
What is actually happening on the server? In normal scenarios, tomcat creates a thread to handle every request. What is happening now?
如果使用Tomcat 8.0.X中默认的NIO连接器,则在整个处理周期内,关于请求的HTTP I / O将不会保留线程.如果使用BIO,则线程将保持不变,直到整个处理周期完成.所有线程都来自线程池,tomcat不会为每个请求创建一个线程.
What is the correct way to ensure that the event stream is sent only once to the same connection/browser session?
浏览器端的eventSource.close()是最佳选择.
What is the correct way to ensure that the event stream is closed and no resource overhead incurs on the server?
不要忘记在服务器端调用AsyncContext.complete().
How to differentiate between GET and POST requests. Why did it choose GET?
浏览器中的EventSource API仅支持GET请求,但在服务器端没有这样的限制.
SSE主要用于从服务器接收事件数据.如果事件发生,浏览器可以及时接收它,并且不需要创建新的轮询请求.
如果需要全双工通信,请尝试使用SSS的WebSocket实例.
Is it too early to use SSE on Tomcat? Any performance issues?
如果我们使用NIO连接器和放大器,应该没有性能问题.异步处理API.我不知道Tomcat NIO连接器是否成熟,但除非我们尝试,否则永远都不会知道.