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 分钟从服务器重新加载一次网格数据 的相关文章

  • 存根方法时出现 InvalidUseOfMatchersException

    我有这个 TestNG 测试方法代码 InjectMocks private FilmeService filmeService new FilmeServiceImpl Mock private FilmeDAO filmeDao Bef
  • Java Runtime.getRuntime().freeMemory() 问题

    我搜索并看到了一些线程 但没有一个能够解决我遇到的具体问题 我正在尝试使用以下方式监视我的内存使用情况Runtime getRuntime freeMemory Runtime getRuntime maxMemory and Runtim
  • Spring Security 自定义过滤器

    我想自定义 Spring security 3 0 5 并将登录 URL 更改为 login 而不是 j spring security check 我需要做的是允许登录 目录并保护 admin report html 页面 首先 我使用教
  • Java:无法从同一包中的不同类访问静态变量

    这很奇怪 因为我有一个可以访问 Frame dimension getWidth 的 Character 类 及其伙伴 getHeight 但是当我想在 Map 类中使用它时 Eclipse 强调了它并且无法给我反馈 运行该程序最终会出现
  • 使用 Ant 将非代码资源添加到 jar 文件

    我正在将 java 应用程序打包成 jar 文件 我正在使用 ant 和 eclipse 我实际上需要在 jar 中直接在根文件夹下包含几个单独的非代码文件 xml 和 txt 文件 而不是与代码位于同一位置 我正在尝试使用includes
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • Integer.parseInt("0x1F60A") 以 NumberformatException 结束

    我尝试从数据库中获取长字符串内的表情符号代码 格式如下 0x1F60A 所以我可以访问代码 但它将是String 起初 我尝试通过执行以下操作来转换变量tv setText beforeEmo getEmijoByUnicode int e
  • 是否可以使用 Flying Saucer (XHTML-Renderer) 将 css 解析为类路径资源?

    我正在尝试将资源打包到 jar 中 但我无法让 Flying Saucer 在类路径上找到 css 我无法轻松构建 URL 来无缝解决此问题 https stackoverflow com questions 861500 url to l
  • 如何将 Mat (opencv) 转换为 INDArray (DL4J)?

    我希望任何人都可以帮助我解决这个任务 我正在处理一些图像分类并尝试将 OpenCv 3 2 0 和 DL4J 结合起来 我知道DL4J也包含Opencv 但我认为它没什么用 谁能帮我 如何转换成 INDArray 我尝试阅读一些问题here
  • 自动生成Flyway的迁移SQL

    当通过 Java 代码添加新模型 字段等时 JPA Hibernate 的自动模式生成是否可以生成新的 Flyway 迁移 捕获自动生成的 SQL 并将其直接保存到新的 Flyway 迁移中 以供审查 编辑 提交到项目存储库 这将很有用 预
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • 如何检测 Java 字符串中的 unicode 字符?

    假设我有一个包含 的字符串 我如何找到所有这些 un icode 字符 我应该测试他们的代码吗 我该怎么做呢 例如 给定字符串 A X 我想将其转换为 AYXY 我想对其他 unicode 字符做同样的事情 并且我不想将它们存储在某种翻译映
  • Java实现累加器类,提供Collector

    A Collector具有三种通用类型 public interface Collector
  • Freemarker 和 Struts 2,有时它计算为序列+扩展哈希

    首先我要说的是 使用 Struts2 Freemarker 真是太棒了 然而有些事情让我发疯 因为我不明白为什么会发生这种情况 我在这里问是因为也许其他人有一个想法可以分享 我有一个动作 有一个属性 说 private String myT
  • HashMap 值需要不可变吗?

    我知道 HashMap 中的键需要是不可变的 或者至少确保它们的哈希码 hashCode 不会改变或与另一个具有不同状态的对象发生冲突 但是 HashMap中存储的值是否需要与上面相同 为什么或者为什么不 这个想法是能够改变值 例如在其上调
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • Spring-ws:如何从没有“Request”元素的 xsd 创建 Wsdl

    尝试为客户端实现 SOAP Web 服务 我需要一个 wsdl 文件来通过soapUI 测试该服务 但正如您在下面看到的 这个 xsd 没有 Request 和 Response 方法 所有请求和响应都被定义为基本 ServiceProvi
  • Android:无法发送http post

    我一直在绞尽脑汁试图弄清楚如何在 Android 中发送 post 方法 这就是我的代码的样子 public class HomeActivity extends Activity implements OnClickListener pr
  • 洪水填充优化:尝试使用队列

    我正在尝试创建一种填充方法 该方法采用用户指定的初始坐标 检查字符 然后根据需要更改它 这样做之后 它会检查相邻的方块并重复该过程 经过一番研究 我遇到了洪水填充算法并尝试了该算法 它可以工作 但无法满足我对 250 x 250 个字符的数
  • 在java中使用多个bufferedImage

    我正在 java 小程序中制作游戏 并且正在尝试优化我的代码以减少闪烁 我已经实现了双缓冲 因此我尝试使用另一个 BufferedImage 来存储不改变的游戏背景元素的图片 这是我的代码的相关部分 public class QuizApp

随机推荐

  • 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