创建 web 应用程序的最佳方法,该应用程序在外部客户端调用他自己的休息服务时动态更新 UI [关闭]

Posted

技术标签:

【中文标题】创建 web 应用程序的最佳方法,该应用程序在外部客户端调用他自己的休息服务时动态更新 UI [关闭]【英文标题】:Best approach to create a webapp which updates the UI dynamically on his own rest service invocation by an external client [closed] 【发布时间】:2016-10-02 12:13:45 【问题描述】:

我有一个 web 应用程序,它公开了一个休息端点。客户端将数据发布到此端点。我需要在不刷新 UI 的情况下显示他们在我的 web 应用中发布的内容。

我的第一种方法是将发布的数据保存在数据库中,并进行 ajax 调用,该调用将不断寻找要显示的新数据。这增加了开销,因为我不需要保存收到的内容。 其次,我遇到了客户端和服务器可以进行全双工通信的 Web 套接字。

有没有更好的方法来做到这一点?

P.S:我的 rest 端点是使用 spring boot 开发的。

【问题讨论】:

你在前端webapp上使用了哪些框架或技术? 为什么不用angular js,它支持数据绑定原理,所以你不需要手动更新前端。 如果您需要在基于浏览器的 UI 中进行实时更新,并且希望避免轮询服务器以获取更新,那么 websockets 是一个很好的解决方案。但是,它们不适用于您的 REST 服务。您可能希望使用 websocket 简单地与前端通信后端的数据已更改,然后您可以使用 ajax/REST 机制来获取更改的数据。 【参考方案1】:

通常有三种方法可以让客户端更新服务器事件:轮询、长轮询和服务器端推送。它们各有优缺点:

轮询

轮询是实现这一点的最简单方法。您只需要在客户端设置一个计时器即可。反复查询服务器以获取更新并重用您已有的代码。

特别是如果你有很多客户端,服务器可能会被大量的 GET 请求淹没。这可能会增加计算和网络开销。您可以通过在服务器端使用缓存代理(作为应用程序的一部分或作为单独的工件/服务/节点/集群)来缓解这种情况。缓存 GET 请求通常很容易。

轮询似乎不是最优雅的解决方案,但在许多情况下它已经足够好了。事实上,轮询可以被认为是做到这一点的“正常”休息方式。 HTTP 指定了类似if-modified-since header 的机制,用于改进轮询。

长轮询

长轮询通过使 GET 请求成为阻塞操作来工作。客户端发出请求,服务器阻塞,直到有新数据。然后请求(可能是很久以前提出的)得到答复。

这大大减少了网络负载。但是有几个缺点:首先你很容易弄错这个。例如,当您将此方法与会话 bean 的服务器端池结合使用时,您的 bean 池可能会很快用完,并且您会遇到绝妙的拒绝服务。

此外,长轮询不适用于某些防火墙配置。一些防火墙可能会认为这个 TCP 连接已经安静了太久,并将其视为中止。然后它可能会默默地丢弃属于该连接的任何数据。

缓存代理和其他中介也可能不喜欢长轮询——尽管我没有具体的经验可以在这里分享。

虽然我花了很多时间来描述缺点,但在某些情况下长轮询是最好的解决方案。你只需要知道你在做什么。

服务器端推送

服务器也可以直接通知客户端有关更改。 Websockets 是详细说明这种方法的标准。您可以使用任何其他 API 来建立 TCP 连接,但在许多情况下 websockets 是要走的路。本质上,TCP 连接保持打开状态(就像在长轮询中一样),服务器使用它来将更改推送到客户端。

这种方法在网络级别上类似于长轮询方法。因此,它也有一些缺点。例如,您可能会遇到相同的防火墙问题。这是 websocket 端点应该发送心跳的原因之一。

最终,哪种解决方案最好取决于您的具体要求。我建议使用简单的轮询机制,如果您可以每隔 10 秒或更短的频率轮询一次,并且如果这不会让您在客户端的电池使用或数据传输量方面遇到麻烦(例如,您正在构建智能手机应用程序) .如果轮询还不够,请考虑其他两个选项。

【讨论】:

以上是关于创建 web 应用程序的最佳方法,该应用程序在外部客户端调用他自己的休息服务时动态更新 UI [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从本地计算机运行 Web 应用程序并在外部服务器上托管文件

在外部托管的 css(特别是 Google CDN jquery-ui.css)中覆盖/删除某些属性的最佳方法是啥?

Cordova RSS 提要链接不会在外部浏览器中打开

CakePHP如何在外部生成其密码

Flutter:在外部存储路径上创建目录 - 路径提供程序 getExternalStorageDirectory()

创建在外部进程中运行的 WPF“控件”