您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

服务器发送事件如何工作

服务器发送事件如何工作

更改此行

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

如果我们不希望浏览器在服务器完成响应后再次重新连接服务器,则需要在浏览器上关闭事件源。

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.
}

我认为Websocket可能更适合您的情况。

如果使用Tomcat 8.0.X中认的NIO连接器,则在整个处理周期内,有关请求的HTTP I / O将不会容纳线程。如果使用BIO,则将保留一个线程,直到整个处理周期结束。所有线程均来自线程池,tomcat不会为每个请求创建线程。

不要eventSource.close()在浏览器端是最好的选择。

不要忘记在服务器端调用AsyncContext.complete()。

浏览器中的EventSource API仅支持GET请求,但在服务器端没有这种限制。SSE主要用于从服务器接收事件数据。如果发生事件,浏览器可以及时接收到它,而无需创建新的请求以对其进行轮询。如果需要全双工通信,请尝试使用SSE的WebSocket。

如果我们使用NIO连接器和异步处理API,应该不会有性能问题。我不知道Tomcat NIO连接器是否成熟,但是除非我们尝试尝试,否则永远不会知道。

其他 2022/1/1 18:14:04 有454人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶