【发布时间】:2014-12-05 08:58:55
【问题描述】:
我有一个 servlet,它将 HTML5 服务器发送的事件发送到 jsp 客户端。 servlet 每隔一秒向客户端发送一次数据。 jsp 客户端实例化一个新的事件源并接收数据。当窗口即将关闭时,jsp客户端在“beforeunload”事件处关闭事件源(如下代码所示)。
但是,我注意到即使在客户端关闭事件源并且浏览器退出之后,服务器仍会继续发送数据。就事件源的文档而言,使用 eventsource.close() 足以阻止客户端重新连接到服务器,并且服务器将停止发送任何进一步的推送通知。
编辑:我已阅读 StackOverflow at this link 上的类似问题。但是,答案是在聊天中讨论的,因此无法访问它。
谁能帮我理解为什么即使在 eventsource.close() 和浏览器退出之后服务器也不会停止发送推送通知?一旦客户端退出,我是否编写任何其他代码来通知服务器停止发送数据?
感谢您的帮助。这是我的简化服务器代码:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
/**
* Servlet implementation class ServletForSSE
*/
@WebServlet("/ServletForSSE")
public class ServletForSSE extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletForSSE() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//content type must be set to text/event-stream
response.setContentType("text/event-stream");
//encoding must be set to UTF-8
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss.SSS");
int i=0;
while (i<1000) {
i++;
System.out.println("------"+ sdf.format(System.currentTimeMillis()).toString());
writer.write("data: "+ sdf.format(System.currentTimeMillis()).toString()+"\n" +"\n\n");
writer.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
这是客户端代码:
<!DOCTYPE HTML>
<html>
<body>
Time: <span id="foo"></span>
<br><br>
<button onclick="start()">Start</button>
<script type="text/javascript">
var eventSource;
function start() {
eventSource = new EventSource("ServletForSSE");
eventSource.onmessage = function(event) {
document.getElementById('foo').innerHTML += event.data+"<br/>";
};
}
function beforeLeaving(){
if (window.addEventListener) { // all browsers except IE before version 9
window.addEventListener ("beforeunload", OnBeforeUnLoad, false);
}
else {
if (window.attachEvent) { // IE before version 9
window.attachEvent ("onbeforeunload", OnBeforeUnLoad);
}
}
console.log("Before Leaving");
}
beforeLeaving();
// the OnBeforeUnLoad method will only be called in Google Chrome and Safari
function OnBeforeUnLoad () {
console.log("Taskss");
eventSource.close();
console.log(eventSource.==true);
return "All data that you have entered will be lost!";
}
</script>
</body>
</html>
【问题讨论】:
-
当你的循环结束时,只需调用 writer.close();
-
writer.close()可能会在doGet()退出后被隐式调用,这也应该停止发送推送通知。当客户端关闭并且循环尚未完成时,他要求 IMO。 -
在代码上抽象差异,好像和stackoverflow.com/questions/25572667/…一样的问题
标签: java javascript html servlets server-sent-events