【问题标题】:Best practice use sam AJAX in multiple browser windows?最佳实践在多个浏览器窗口中使用 sam AJAX?
【发布时间】:2010-09-19 13:19:16
【问题描述】:

我正在开发一个具有某种实时更新的网站。 现在该网站是使用数据集当前 ID 的 javascript 变量生成的。 然后在几秒钟的时间间隔内,通过当前 ID 进行 AJAX 调用,如果有新的内容,服务器将其与最新的 ID 一起返回,然后在 javascript 中更新。 很简单,但是问题来了。

如果用户多次打开同一个页面,每个页面都会执行此 AJAX 请求,这会产生繁重的服务器负载。

现在我想到了以下方法:

网站加载了当前时间戳和当前数据集 ID 的 javascript 变量。 例如,我想要的刷新间隔是 3 秒。

在网站中,间隔计数器每秒钟计数一次,每次时间戳达到(timestmap % 3===0) 返回 true 的状态时,都会更新内容。 链接看起来像http://www.example.com/refresh.php?my-revision=123&timestamp=123456

现在这应该确保每个浏览器窗口调用相同的 URL。 然后我可以打开浏览器级别的缓存。

但我不太喜欢这种解决方案。 我宁愿在 Cookie 中添加另一层数据共享。 这应该不是什么大问题,我可以将每个请求存储在一个由时间戳和数据修订命名的 cookie 中,TTL 为 10 秒左右,然后先检查它的存在。

但是

页面将同时执行请求。因此,浏览器缓存和 cookie 的整个逻辑可能无法正常工作,因为请求是同时发生的,而不是一个接一个。

所以我考虑将当前连接限制为 1 个服务器端。但是我至少需要一个额外的虚拟主机,因为我真的不想为整个页面这样做。 这让我遇到了有关跨站点策略的问题!

当然有一些超级复杂的负载平衡解决方案/服务器端解决方案绑定到请求 uri 和 ip 地址或其他东西,但那都是极端的矫枉过正!

一定是通病!想想脸书聊天。我真的不认为他们会在您打开的每个窗口中完成所有请求...

有什么想法吗?我真的被这个卡住了!

也许我可以做一些跨窗口的 Javascript 通信?如果它们都在同一个域上,应该不是问题吗?

我可以做的当然是服务器端缓存。这至少避免了数据库连接和密集计算......但它仍然是我想避免的请求。

【问题讨论】:

    标签: javascript html ajax partial-page-refresh


    【解决方案1】:

    您可能想查看 CometOrbited 。 这最好通过服务器推送技术解决。

    【讨论】:

    • 谢谢,这是一篇关于实时和增量更新技术的好文章!但我担心它不能涵盖我遇到的具体问题......但它可能会指出我可能会找到解决方案的不同方向! (为好资源+1!)
    • 通过使用 STOMP(或 XMPP),您可以为不同的数据集 ID 定义不同的通道。 Orbited 支持这两种协议。然后,您将对数据集的每个 ID 进行单独的通道和实时更新。我提出了 Comet,因为它大大减少了前端的负载。如果您集成了良好的后端(插入/更新数据集时的信号/触发器),您也将优化后端。
    【解决方案2】:

    第一件事是:使用MemcacheRedis 或其他任何方式进行服务器端缓存。因此,您可以抵御三台执行请求的机器。但你知道的。

    坦率地说,我认为您使用 cookie 是正确的(但请参阅下面的更现代的选项)——它们由所有窗口实例共享,易于查询等。您的轮询逻辑可能如下所示:

    在轮询间隔上:

    • 查看内容 cookie:它比您现有的更新鲜吗?如果是这样,使用它就完成了。
    • 查看状态cookie;是否有其他人主动轮询(例如,cookie 已设置且未过时)?如果是,请稍后再回来。
    • 设置状态 cookie:我正在(现在)积极投票。
    • 请求

    回应:

    • 如果新数据比内容 cookie 的(可能更新的)内容更新,请将内容 cookie 设置为新数据
    • 清除状态 cookie如果您是设置它的人

    基本上,状态 cookie 充当信号量,向所有窗口实例指示某人在某处正在更新内容。

    您的内容 cookie 可能直接包含内容,或者如果您的内容很大并且您担心会遇到限制,您可以让每个页面都有一个隐藏的 iframe,每个页面都有一个唯一的名称,并让您的 Ajax更新将输出写入 iframe。内容 cookie 将发布最新 iframe 的名称,其他看到有新内容的窗口可以使用 window.open 获取该 iframe(因为如果您使用 window.open 不会打开窗口现有名称)。

    注意比赛条件。尽管任何给定页面中的 JavaScript 都是单线程的(除非明确使用 web workers),但您不能指望其他窗口中的 JavaScript 一定在同一线程上运行(它在某些浏览器上,而不是在其他浏览器上——哎呀,在 Chrome 上它甚至不是相同的进程)。我也不知道写 cookie 有没有原子性的保证,所以你要保持警惕。

    现在,HTML5 定义了一些有用的 inter-document communication mechanisms,因此您可能会考虑查看它们是否存在并在使用这种 cookie 方法之前使用它们,因为它们现在可以在现代浏览器中工作,但不能在旧浏览器中使用'现在可能不得不处理。不过,在支持它的浏览器上,很棒!

    Web storage 也可能是一个值得研究的选项,作为上述方面的一个方面,但您的客户几乎肯定必须授予您的应用权限,这也是一个相当新的事物。

    【讨论】:

    • 谢谢!您使用了正确的词“保证编写 cookie 的原子性”,这正是我所关心的!无论如何,除了您的解决方案之外,我只会添加 2-3 秒的随机时间,直到在每个窗口中发出请求,我将冲突的可能性降到最低,如果发生冲突......这不是一个大问题!跨度>
    • @Joe Hopfgartner:请注意,我说过我知道有保证。 :-) 所以要小心。玩得开心!
    • 是的,我认为很可能没有,它取决于浏览器。因此随机时移:)
    猜你喜欢
    • 2020-05-09
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 2017-03-21
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多