Vaadin-grid.getDataProvider().refreshAll();更新浏览器后不工作

Vaadin-grid.getDataProvider().refreshAll();更新浏览器后不工作,grid,vaadin,Grid,Vaadin,你好吗?更新包含网格的选项卡后,我有一个推送的详细信息,我使用的是vaadin 8.0.4 ,google chrome更新了,我的例子就在这里 我的应用程序由存储在mongodb中的数据组成,当我在db中进行直接更改时,它会每隔30秒反映在网格中,使用push时,它总是在单个选项卡上工作,当我更新选项卡或创建新选项卡时出现问题,push似乎断开连接,我的网格不再更新,奇怪的是,我在访问应用程序的第一个选项卡中添加了@PreserveOnRefresh和@PreserveOnRefresh,如果

你好吗?更新包含网格的选项卡后,我有一个推送的详细信息,我使用的是vaadin 8.0.4 ,google chrome更新了,我的例子就在这里

我的应用程序由存储在mongodb中的数据组成,当我在db中进行直接更改时,它会每隔30秒反映在网格中,使用push时,它总是在单个选项卡上工作,当我更新选项卡或创建新选项卡时出现问题,push似乎断开连接,我的网格不再更新,奇怪的是,我在访问应用程序的第一个选项卡中添加了@PreserveOnRefresh和@PreserveOnRefresh,如果推送在更新后仍然有效,则非常奇怪

此实例检查my db中的更改

private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);

我使用网格更新,带有

grid.getDataProvider().refreshAll()
我甚至尝试通过书12.16.4中描述的模式来广播标签。向其他用户广播 因为如果活动通知在所有选项卡中继续,但网格不会,只有在原始选项卡中。


更新: 在这个示例应用程序中,问题实际上是登录,当我删除它时,如果一切都像推送一样正常工作。但仅当我删除登录名时

@Override
public void receiveBroadcast() {
   access(() -> {
    //Notification.show(message);
    //grid.getDataProvider().refreshAll();
    getNavigator().removeView(MonitorCrudView.VIEW_NAME);
    getNavigator().addView(MonitorCrudView.VIEW_NAME,new MonitorCrudView(this));
    getNavigator().navigateTo(MonitorCrudView.VIEW_NAME);
    Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
   });
}
详细信息是,当我启用AccessContro,并根据您看到的以管理员身份输入时,在执行上述方法时,我会得到一个异常类型“没有链接到当前线程的请求”;来自“CurrentUser”类

但在这里,vaadin 8.0.4有一点变化


更新:

在这个类中,我添加了向所有UI广播的按钮

  • 以管理员身份登录
  • 点击更新网格
  • 应该给出一个类型异常
java.util.concurrent.ExecutionException: java.lang.IllegalStateException:没有绑定到当前线程的请求

  • 刷新UI后不会继续抛出exeption 但是,当在incognito选项卡中打开时,它总是在更新之前抛出一次异常

  • 与基础项目和mongo db以及

专用静态计划执行器服务计划程序= Executors.newScheduledThreadPool(5)


我总是从上面得到相同的异常,并且从不使用push更改视图。免责声明:这更适合作为注释,但不适合分配的空间


缔约国指出:

由于服务器实现重用响应实例的方式,当前响应不能在后台线程中使用

与此同时,该报告的表述有些含糊不清,即:

请注意,runnable可能会在不同的线程上调用,或者稍后在当前线程上调用,这意味着在执行命令时,自定义线程局部变量可能没有预期的值

上面的语句可以解释为什么
getCurrentRequest()
方法中
VaadinService.getCurrentRequest()为空

尽管如此,似乎UI.getCurrent()在后台线程中运行时会返回一个实例,这也是和vaadin的书中建议的:

您的代码不是线程安全的,因为它在访问UI之前不会锁定VaadinSession。首选模式是使用UI.access和VaadinSession.access方法,如访问块内部所述。除了正确处理会话锁定外,Vaadin还会自动设置相关的threadlocals

总之,我建议将对
getCurrentRequest().getWrappedSession()
的所有调用替换为
UI.getCurrent().getSession()
;,例如:

UI.getCurrent().getSession().getAttribute(CURRENT_USER_SESSI‌​ON_ATTRIBUTE_KEY);


我用您的示例对此进行了测试,效果很好。

您是否有机会在github或类似平台上共享一个示例(忘记数据库只是使用一些静态数据),以及复制问题的步骤列表?非常感谢,我非常感谢,我正在尝试在没有mongodb的情况下复制错误,在应用程序本身的示例8.0.4中,我仍然没有实现它@MorficHello@Morfic你在某种程度上是哈哈哈,我不知道这是不是太多的要求,但你能看到示例github中的代码吗?我检查了你的代码,请看下面可能的回答。离题:我目前正在旅行,因此可能无法快速回复您的评论。非常感谢您的帮助。如果浏览器运行正常,请更改浏览器,并使用我的ScheduledExecutorService进行更新,该服务不需要按钮,现在是grid.getDataProvider()。RefreshAll();不会刷新所有的UI,但实际上,第一次刷新就可以了
UI.getCurrent().getSession().getAttribute(CURRENT_USER_SESSI‌​ON_ATTRIBUTE_KEY);
UI.getCurrent().getSession().setAttribute(CURRENT_USER_SESSI‌​ON_ATTRIBUTE_KEY, currentUser);