Vaadin 8:每 1 分钟从服务器重新加载一次网格数据

2023-12-05

我正在尝试为网格提供自动刷新功能,基本上,每“n”秒用来自服务器的最新数据更新网格。

每当用户启用自动刷新时,我就能够实现 PollListner。

                UI ui= TestUI.getCurrent();
                Boolean value = isRefreshChkBox.getValue();
                PollListener listener = e -> {
                    explorer.reloadUI();
                };
                if (value) {

                    String refreshRateValue = refreshRateTxtField.getValue();
                    int refreshRate = Integer.valueOf(refreshRateValue);
                    int millis = (int) TimeUnit.SECONDS.toMillis(refreshRate);

                    absUI.setPollInterval(millis);

                    absUI.addPollListener(listener);
                } else {
                    absUI.setPollInterval(-1);
                    absUI.removePollListener(listener);
                }

使用上面的代码,我在每次启用自动刷新时添加 PollListener,并在禁用时将其删除。

我在这里发现了类似的问题VAADIN 7:以 5 分钟为间隔刷新 Vaadin 视图的最简单方法是什么?

但我想了解的是,是否有更好的方法来实现简单的用例 AutoRefresh UI? PollListener 应该在哪里实现?我想为视图创建一次 PollListener ,并在每次用户更改刷新率时更新 PollInterval 。

有没有关于哪种方法更好的指示,或者 Vaadin 是否有全新的概念来实现这一目标?

TIA


See the Leif Åstrand 的正确答案。我将添加一些讨论,以及使用轮询和推送的完整示例应用程序。

Vaadin 8 有两种无需用户做出手势即可自动更新信息显示的方式:轮询和推送。

Polling

在 Vaadin 8 中投票功能, you 设置轮询间隔您的毫秒数UI子类。默认值为-1禁用轮询。

myUI.setPollInterval( ( int ) TimeUnit.MINUTES.toMillis( 1 ) );  // Specify milliseconds for polling interval.

启用后,安装在用户 Web 浏览器中的 Vaadin JavaScript 库会与 Vaadin 服务器签入。成为一个PollNotifier,UI 签入会导致服务器端触发一个事件。

如果您定义一个实现了PollListener接口,您的实例将有它的poll调用的方法。

注册您的PollListener。找回一个Registration目的。该对象提供了一个remove如果需要的话,取消注册您的侦听器的方法。

您可以选择定义您的PollListener使用 lambda 语法、匿名内部类或单独定义的类。

Registration registration = this.addPollListener( new UIEvents.PollListener() {
    @Override
    public void poll ( UIEvents.PollEvent pollEvent ) {
        System.out.println( "TRACE - PollListener::poll running. " + Instant.now() );
        …
    }
} );

或者,lambda 语法:

Registration registration = this.addPollListener( ( UIEvents.PollListener ) pollEvent -> {
    System.out.println( "TRACE - PollListener::poll running. " + Instant.now() );
    …
} );

在此调用期间,您的代码可以注册Runnable在方便的时候与您一起调用UI子类。

That Runnable更新您的中包含的小部件的工作UI子类。记得never从后台线程访问或修改小部件。你可能会侥幸逃脱,也可能会导致可怕的事情发生。确保安全:始终致电UI::access通过一个Runnable访问小部件。那Runnable将在您的网络应用程序的主用户界面线程上运行,该线程负责您的UI子类实例。

getUI().access( new Runnable() {
                    @Override
                    public void run ( ) {
                        subscriber.refresh( new ArrayList <>( statusList ) ); // Copy the list in case the `Grid` modifies it, such as sorting.
                    }
                } );

Pros

使用轮询功能的好处是您必须执行的编程比使用轮询功能更简单Push(下面讨论)。在了解自动非用户生成的更新时,轮询可能是更好的途径。

一个简单的方面是您的每个实例UI子类负责自己的轮询,选择是否以及何时进行轮询以及控制轮询的频率。每个UI子类实例调用自己的实例setPollInterval方法。更多的轮询可能对用户来说很好,但闲聊会增加网络流量,从而使您的网络管理员变得暴躁。所以你可以通过以下方式调整频率UI子类实例。请记住,每个用户不仅拥有自己的UI子类实例,而且 Vaadin 8 能够运行多窗口/选项卡应用程序。每个网络浏览器中的一个网络应用程序可以打开多个窗口/选项卡,每个窗口/选项卡都运行自己的相同或不同的实例UI子类。

Cons

美学上的一个缺点是轮询破坏了 HTTP 设计的请求-响应优雅性。虽然这是我最讨厌的事情,但那艘船很久以前就已经航行了,所以我不会在这里浪费字节来抱怨使用文档传递系统作为交互式客户端-服务器应用程序架构。

更实际的缺点是网络上不必要的流量。如果您能够使用Push via WebSocket or Webpush,然后客户端和服务器之间一直保持一个开放的连接,流量非常小,直到服务器生成要传达给客户端的事件。但请注意,WebSocket 很容易被防火墙和代理击败,并且 Webpush 可能无法实现/支持,在这种情况下,Vaadin 中的 Push 实现(氛围框架图书馆由async-io.org)可能会退回到轮询技术。

另一个缺点是每个客户端都进行自己的重复轮询,并且每个客户端都触发服务器端的单独执行,例如在数据库中搜索新数据,效率低下。如果您有许多客户端都使用同一组不可变对象,则推送可以更有效地执行对新数据的单次搜索并将同一组数据对象传递给所有客户端。

Push

Vaadin 与 Atmosphere 的结合(上面链接)vastly简化在您的网络应用程序中使用推送技术。然而,与轮询功能相比,它有更多的移动部件,因此稍微复杂一些。

首先,启用推送@Push注释在你的UI子类。

然后使用以下方法安排每分钟触发一个事件ScheduledExecutorService。设置该执行器ServletContextListener。有关这一切,请参阅下面的示例代码。

Pros

就可使用的网络流量而言,推送可以非常高效WebSocket技术或Webpush, 正如刚才提到的。

Cons

不幸的是,WebSocket 可能会被防火墙和代理击败。而且 Webpush 是新事物,可能不会得到广泛支持。在这种情况下,Vaadin/Atmosphere 可能会转而使用轮询方法。

另一个缺点是编码有点复杂。刚接触这项工作的程序员可能需要一段时间才能掌握各种移动部分。

  • 您需要服务器端的后台线程来跟踪时间,在我们的例子中每分钟触发一次。现代方法是使用ScheduledExecutorService处理线程和触发时间表。
  • 要设置该执行程序服务,您需要实现ServletContextListener如下所述。

请注意,某些推送方法(尤其是 WebSocket)涉及维护开放的网络连接。因此,这会消耗服务器计算机上的资源,例如端口号。

示例应用程序

我使用 Vaadin 8.6beta1 构建了一个完整的工作示例应用程序。这个应用程序支持both轮询和推送。不确定您是否会在真正的网络应用程序中混合使用两者,但也许吧。

访问主要文件在我的 Google 云端硬盘上。添加到通过 Maven 原型创建的项目vaadin-archetype-application由 Vaadin 有限公司提供

警告:这个例子是花了几天时间兼职拼凑起来的。因此,它可能是也可能不是生产就绪的代码,并且可能会也可能不会显示正确的技术。但希望它能帮助指导新手。

警告:我不是这个领域的专家。因此,将我上面所有的讨论和我的示例代码与盐粒。做你自己的研究和学习。

该应用程序允许您通过单选按钮启用和禁用每种方法。您还可以通过单击强制立即刷新现在手动刷新 button.

enter image description here

绿色阴影表示自上次刷新以来更改的值。

您可以运行多个窗口。观看它们一起更新、单独更新或不全部更新,具体取决于您的单选按钮设置。

enter image description here

Database

此示例应用程序的主要思想是模拟一个数据库,维护大约十件设备/流程/人员/其他内容的当前状态。每个状态都由数字 1-10 标识。每个状态都有一个包含 10 个值(1-9)的域的状态。每个状态都会记录最后一次更新的时刻。

这十个状态记录在 Vaadin 中显示为行Grid widget.

所有这些数据都记录在关系数据库中,H2数据库引擎。作为演示,我们不需要持久性,因此数据库位于内存中。后台线程随机更新数据库中的状态行。

MyDbService.java

此数据库服务代码建立我们的内存 H2 数据库,定义状态表并填充十行。该类还可以随机更新某些行的值。您可以要求检索List of Status表示当前存储值的对象。

Status.java

每个状态记录在 Java 中表示为Status类,一个简单的 POJO。

生命周期

瓦丁基于Java小服务程序技术。您的 Vaadin 应用程序是一个大型 Servlet 实现。作为 servlet,它响应用户 Web 浏览器传入的请求。

在第一个传入请求之前,我们需要做一些设置工作。一方面,我们需要建立数据库并使用十个状态记录填充该数据库。

Servlet规范要求所有网络容器支持ServletContextListener界面。如果您编写一个实现该接口的类,并将其声明给 Web 容器,那么它将在第一个请求之前和最后一个请求之后调用。

在我们的示例中,我们使用该挂钩来建立数据库。我们还设置了一个后台线程,可以随机更改存储的状态记录,以模拟用户的更新或来自提要的新数据。

上下文监听器

这是我们的例子ServletContextListener.

向我们的 Web 容器声明其存在的最简单方法是通过@WebListener注解,但您可以根据部署场景的需要选择其他路由。

@WebListener
public class MyServletContextListener implements ServletContextListener {
…

MyUI.java

这个 Vaadin Web 应用程序的入口点是我们的子类UI, MyUI.java。它有两项工作:(a) 将我们的用户界面内容显示在屏幕上,以及 (b) 将自己注册为PollListener对轮询更新做出反应。

DataDisplayLayout.java

这是我们的用户界面内容。这是此示例应用程序的核心。它显示 Vaadin 网格,其显示将使用新数据进行更新。

DataDisplayLayoutRefreshManager.java

该经理负责监督注册我们的实例的发布-订阅(发布-订阅)模型DataDisplayLayout想要通过推送更新。

这里使用弱引用的集合来跟踪订阅者。所以订阅的DataDisplayLayout实例可以优雅地通知他们不再更新的愿望,或者实例可以简单地超出范围,最终作为订阅者被删除。

轮询方法不需要这个管理器,因为我们的每个实例UI子类(MyUI)正在单独轮询服务器。

mytheme.scss

Vaadin 网格中表示新值的单元格的绿色通过以下方式设置CSS。在 Vaadin 8 中,我们通过编辑mytheme.scss发现文件埋在你的项目中webapp文件夹。

这里我们定义样式名称fresh_row.

@import "../valo/valo.scss";

@mixin mytheme {
  @include valo;

  // Insert your own theme rules here
  .v-grid-row.fresh_row > td:nth-child(2) {
    background-color: honeydew;
  }
}

我们必须通过实现样式生成器将该样式名称分配给 Vaadin 网格行。

this.grid.setStyleGenerator( ( StyleGenerator ) o -> {
    Status s = ( Status ) o;
    if ( s.getUpdated().isAfter( this.whenRowLastUpdated ) ) {
        return "fresh_row";
    } else {
        return null;
    }
} );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vaadin 8:每 1 分钟从服务器重新加载一次网格数据 的相关文章

  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 在 Shiny 中的用户会话之间共享反应数据集

    我有一个相当大的反应数据集 该数据集是通过轮询文件然后按预定义的时间间隔读取该文件而派生的 数据更新频繁 需要不断重新加载 诚然 重新加载可以增量完成并附加到 R 中的现有对象 但事实并非如此 然而目前 尽管会话中的数据相同 但此操作是针对
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • Oracle 的 Dataframe 创建具有区分大小写列的表

    火花 2 1 1 我正在拯救我的dataframe as an Oracle表 但生成的 Oracle 表有 区分大小写 列 val properties new java util Properties properties setPro
  • RapidMiner 在 Java 应用程序中的集成

    我在 RapidMiner 中有一个文本分类过程 它从指定的Excel表格中读取测试数据并进行分类 我还有一个小型 Java 应用程序 它正在运行这个进程 现在我想在我的应用程序中创建文件输入部分 以便每次我都能够从我的应用程序 而不是从
  • 沿一个方向偏移多段线

    我正在寻找一种方法来偏移通过 xy 坐标在一个方向 在 R 中 定义的任意曲线 我可以使用 polyclip 包在两个方向上偏移曲线 library polyclip gt polyclip 1 10 0 built from Clippe
  • 为什么哈希图查找是 O(1) 即常数时间?

    如果我们从 Java 的角度来看 那么我们可以说 hashmap 查找需要恒定的时间 但内部实施又如何呢 它仍然需要在特定的存储桶 哪个键的哈希码匹配 中搜索不同的匹配键 那么为什么我们说哈希图查找需要恒定的时间呢 请解释 在对所使用的哈希
  • 闪亮的 Favicon 使用 URL 但不使用本地文件路径

    我正在尝试向我的 R Shiny 应用程序添加一个图标 并且我想使用本地图像文件 以便它可以在没有互联网连接的情况下运行 使用埃姆斯给出的例子here我有一个程序 当它使用 NOAA 徽标的 url 时 它将显示网站图标 但是 当我将该确切
  • Delphi 中的这些 Windows API 签名有什么区别?

    在 Delphi 中查看 Windows pas 我发现有几个签名 LoadLibrary A or W 用于加载特定模块 它们之间有什么区别 我是否可以相信始终为所有类型的 Windows 平台调用 LoadLibrary Windows
  • c# GDI+,在循环中创建 LinearGradientBrush(内存泄漏)

    今天我遇到了一个两难的境地 我创建了一个使用 GDI 在表单上绘图的应用程序 每秒由计时器触发绘图 draw 方法使用 for 循环来迭代对象集合 如果它们处于某种状态 则绘制它们 我想使用 LinearGradientBrush 来绘制它
  • 使用服务别名进行依赖注入

    在我的应用程序中 我有短信服务 该服务是一个简单的 POPO 它采用驱动程序的实例来执行实际的 SMS 功能 想象一下我有两个司机 mock driver and gateway driver它们在中被定义为类似的东西services部分
  • 在 r 中重组数据:reshape、dcast、melt...似乎对此数据框不起作用

    这是我导入的数据帧的前几行的示例 在完整数据集中 主题变量总共有五个级别 因子 其他两个是代数 II 和几何 SID firstName lastName subject sumScaleScore sumPerformanceLevel
  • Powershell:从同一对象中引用另一个对象属性中的对象属性?

    晚上好 各位 只是一个小问题 是否有可能 我知道我可以通过将其称为空对象然后一一添加属性来做到这一点 Obj New Object PSObject Obj name hello Obj type Obj name world 有没有办法将
  • 如何访问文档文件夹

    我已将所有日志重定向到应用程序文档文件夹中的文件 我知道如何通过 xcode 访问它 我必须将我的 ipad 连接到 MAC 并在 xcode 中通过 Organizer gt device 我可以访问文档文件夹 现在我想在没有 xcode
  • 如何有效地查找 Firebase 中一组节点是否包含另一组节点中包含的元素?

    我正在构建一个社交媒体数据库架构 其中有用户 关注者 标签和帖子 为了符合 firebase 模型 我按照 firebase 文档中的建议展平了结构 如下所示 我遇到的问题是 当用户选择一个标签并看到 tagPosts 表中的一堆帖子均与返
  • INT 数据库字段与 VARCHAR 类型的比较

    我有以下存储过程 没有编写完整的存储过程 但其中一些是 course int null SET query query Where course id cast course as varchar 我想知道我何时将 course 转换为 V
  • 使用 Watir 将多个文件传递到输入节点(使用 Ruby)

    所以我遇到了一些障碍 我正在尝试自动化一个测试用例 其中我需要将多个文件传递到输入节点 但我不知道如何执行此操作 我可以使用 Mechanize 或 Watir 但在自动化领域似乎相对重要的主题上发现的信息很少 在下面的代码片段中 我将 W
  • 回调还是承诺? [复制]

    这个问题在这里已经有答案了 在使用 javascript 异步错误捕获机制时 我最终问自己使用 Promise 与回调有什么区别 除此之外 Promise 可能是更糖化的语法 例如 让我们考虑 function setPromise var
  • SQL 更新、删除和插入同时进行

    我只是对某件事感到好奇 假设我有一个表 我将更新该值 然后删除它 然后插入一个新的 1 如果我以这种方式编写编码 这将非常容易 UPDATE PS EMAIL ADDRESSES SET PREF EMAIL FLAG N WHERE EM
  • 不要将 Android 上下文类放置在静态字段中;这是内存泄漏

    我有一项服务有BeaconNotificationsManager 我想访问这个BeaconNotificationsManager in my Activity 目前我的BeaconNotificationsManager is stat
  • 为什么我不能使用密集排名作为 SQL“排名分数”?

    我正在使用 SQL 中的 dendense rank 函数来解决 leetcode 的 排名分数 问题 https leetcode com problems rank scores description select Score den
  • 有条件地更改目标框架版本

    我正在尝试将 ifdef d 代码库编译到两个不同的目标框架 即 3 5 和 4 0 我尝试修改解决方案中的 proj 文件但无济于事 看来 MSBuild VS2012 没有通过 UI 获取解决方案配置更改 这是 proj 文件之一的片段
  • Vaadin 8:每 1 分钟从服务器重新加载一次网格数据

    我正在尝试为网格提供自动刷新功能 基本上 每 n 秒用来自服务器的最新数据更新网格 每当用户启用自动刷新时 我就能够实现 PollListner UI ui TestUI getCurrent Boolean value isRefresh