我的应用程序由存储在mongodb中的数据组成,当我在数据库中进行直接更改时,它经常在30秒内反映在网格中,使用push,它总是在单个选项卡上工作,当我在更新选项卡或创建一个新选项卡,推送似乎已断开连接,我的网格不再更新,奇怪的是我添加了@PreserveOnRefresh并在第一个访问应用程序的选项卡中,如果推送工作甚至在更新很奇怪。
此实例检查我的数据库中的更改
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时,我按照您所看到的那样输入admin,在执行上述方法时,我得到类型"没有链接到当前线程的请求&# 34; ;来自" CurrentUser"类 https://github.com/vaadin/archetype-application-example/blob/master/mockapp-ui/src/main/java/org/vaadin/mockapp/samples/authentication/CurrentUser.java
但是在vaadin 8.0.4这里改变了一点
public final class CurrentUser {
/**
* The attribute key used to store the username in the session.
*/
public static final String CURRENT_USER_SESSION_ATTRIBUTE_KEY = CurrentUser.class
.getCanonicalName();
private CurrentUser() {
}
/**
* Returns the name of the current user stored in the current session, or an
* empty string if no user name is stored.
*
* @throws IllegalStateException
* if the current session cannot be accessed.
*/
public static String get() {
String currentUser = (String) getCurrentRequest().getWrappedSession()
.getAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY);
if (currentUser == null) {
return "";
} else {
return currentUser;
}
}
/**
* Sets the name of the current user and stores it in the current session.
* Using a {@code null} username will remove the username from the session.
*
* @throws IllegalStateException
* if the current session cannot be accessed.
*/
public static void set(String currentUser) {
if (currentUser == null) {
getCurrentRequest().getWrappedSession().removeAttribute(
CURRENT_USER_SESSION_ATTRIBUTE_KEY);
} else {
getCurrentRequest().getWrappedSession().setAttribute(
CURRENT_USER_SESSION_ATTRIBUTE_KEY, currentUser);
}
}
private static VaadinRequest getCurrentRequest() {
VaadinRequest request = VaadinService.getCurrentRequest();
if (request == null) {
throw new IllegalStateException(
"No request bound to current thread");
}
return request;
}
}
更新
在这堂课中,我添加了向所有用户界面广播的按钮。
java.util.concurrent.ExecutionException: java.lang.IllegalStateException:没有绑定到当前线程的请求
刷新UI后不继续抛出exeption 但是当在隐身标签中打开时,它会在更新之前抛出异常一次。
使用基础项目和mongo db加上
private static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
我总是从上面得到相同的例外,并且永远不会用push
更改视图答案 0 :(得分:1)
免责声明:这更适合作为评论,但不适合分配的空间。
VaadinService.getCurrentRequest()
API doc表示:
当前的响应不能用于例如后台线程,因为服务器实现重用响应实例的方式。
与此同时,UI.access()
javadoc有些模棱两可,说明:
请注意,runnable可能在另一个线程上调用,或者稍后在当前线程上调用,这意味着执行命令时自定义线程本地可能没有预期的值
以上陈述有助于解释VaadinService.getCurrentRequest()
方法中getCurrentRequest()
为空的原因。
尽管如此,似乎UI.getCurrent()在后台线程中运行时返回一个实例,同样由this vaadin forum post和vaadin book建议:
您的代码不是线程安全的,因为它在访问UI之前不会锁定VaadinSession。首选模式是使用Book of Vaadin section 11.16.3.中描述的UI.access和VaadinSession.access方法。在访问块内部,Vaadin除了正确处理会话锁定外,还自动设置相关的threadlocals。
总之,我建议将getCurrentRequest().getWrappedSession()
的所有来电替换为UI.getCurrent().getSession()
;,例如:
UI.getCurrent().getSession().getAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY);
或
UI.getCurrent().getSession().setAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY, currentUser);
我用你的样品进行了测试,结果很好。