java - Vaadin 10长时间处理时如何防止连接松动?
问题描述
我有一个简单的代码,在单击按钮后模拟数据处理:
@Route("long")
public class LongWait extends VerticalLayout {
public LongWait() {
Button processButton = new Button("Process");
processButton.addClickListener(event -> process());
add(processButton);
}
//imitates processing data:
//should sleep for 10 minutes and then add "finished" label
//instead loose connection after 5 minutes
private void process() {
try {
Thread.sleep(10 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
add(new Label("finished"));
}
}
问题是 - 在“处理”5 分钟后,浏览器与服务器的连接松动。
为什么会发生以及如何避免它?
(我真的要处理大量数据。)
Vaadin:10.0.3
Tomcat:9.0.8
Java:1.8.0_162
UPD:process()
方法完成后(10分钟过去)我在日志中收到以下错误
:
java.lang.UnsupportedOperationException: Confirmed duplicate message from the client. Expected sync id: 1, got 0. Message start: {"csrfToken":"964b296a-b3ab-48d2-b67f-5e46080f8949","rpc":[{"type":"event","node":4,"event":"click","data":{"event.shiftKey":false,"event.metaKey":false,"event.detail":1,"event.ctrlKey":false,"event.clientX":75,"event.clientY":42,"event.altKey":false,"event.button":0,"event.screenY":160,"event.screenX":76}}],"syncId":0,"clientId":0}
at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:302)
at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1487)
at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:300)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:412)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1385)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
解决方案
这里发生的是按钮单击侦听器直接从 HTTP 请求运行,直到从单击侦听器返回之前不会有任何响应。HTTP 请求通常在一分钟后超时。
解决此问题的最佳方法通常是使用 Vaadin 提供的服务器推送功能。这将起作用,以便单击处理程序在单独的线程中启动缓慢的工作,然后立即返回。处理完成后,将结果单独推送到 UI 中。
您可以在https://vaadin.com/docs/v10/flow/advanced/tutorial-push-access.html中阅读有关如何执行此操作的概述。
推荐阅读
- node.js - NodeJS 中的 REST API 并行 bash 命令
- impala - 如何查看 impala 表中的分区数
- python - 如何获取我服务器所有成员的公会信息
- javascript - 当用户按住 ctrl 按钮时,javascript window.open() 方法仍然在新选项卡中打开
- php - Laravel:如何从表中获取除第一行之外的所有行?
- android - 应用自定义线程池内的迷你线程池
- python - Python Discord 表情符号机器人
- flutter - 在导航到下一个选项卡之前显示消息对话框
- python - 如何在指数分布的尾部生成随机数?
- flutter - 我在颤振应用程序中获得了两个 appBar。我正在尝试在 Flutter 应用程序中添加 Drawer 小部件和 TabBar 小部件