【问题标题】:Javascript: two connections per client?Javascript:每个客户端两个连接?
【发布时间】:2012-01-18 07:20:41
【问题描述】:

我正在开发一个实现长轮询的应用程序,因为我希望用户在收到通知后立即收到通知。我有这部分工作,但我还需要使用 javascript 函数对其进行扩展,该函数每 20 秒向服务器发送一次“心跳”。

我的问题:如何在不完全中断代码 20 秒的情况下执行此操作(以便在计数时仍执行其他 javascript),有没有办法为此使用第二个连接?因为我不希望在向用户发送心跳时中断我的长轮询。

有什么想法吗?

【问题讨论】:

  • 一个超时时间为 20000 毫秒的计时器如何,在完成服务器异步请求后,再休眠 20000 毫秒?
  • 如果客户端中断了 http 连接,你的服务器肯定会注册这个。你应该能够赶上这个事件。
  • @bennedich:不要认为连接关闭时会产生事件,我不知道服务器如何知道它。
  • @DorinDuminica:我不能让它休眠 20000 毫秒,因为异步连接应该一直可用..
  • @Sled:好的。 setTimeout 或 setInterval 应该能够不时地发送一个异步请求 (XMLHttpRequest) 而不会中断您的其他代码。

标签: javascript ajax multitasking long-polling heartbeat


【解决方案1】:

使用setInterval(yourHearbeatFunction, 20000),它不会锁定Javascript执行线程。因此,longpolled 请求将在收到后立即处理。

【讨论】:

  • 这样做的问题是,如果单个心跳需要超过 20 秒才能完成,您将开始堆叠打开的请求,这会降低浏览器的速度。这很可能不是问题,因为超时时间为 20 秒,但如果它更短就会出现问题。
【解决方案2】:

虽然下面的线程已经很老了,但它表明浏览器在任何时候都允许通过 XMLHttpRequest 进行多个连接。

How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

如果您使用 XMLHttpRequest 或任何其他实现 comet 的方式进行长轮询会话,您仍然可以创建另一个请求到同一服务器作为 setInterval 或 setTimeout 函数的一部分,直到达到浏览器施加的有限限制,您需要确保在 XHR 的构造中包含异步标志:

var heartbeatXhr = new XMLHttpRequest();
heartbeatXhr.open('GET', '/polling-url', true); // true for asynchronous

【讨论】:

    【解决方案3】:

    您无需为要实现的目标维护多个连接。 Javascript 的异步特性允许连接在处理其他事情时保持活动状态。你可能认为 javascript 的 XHR 是阻塞的,因为它是单线程的。

    由于事件循环模型,javascript 中的 XHR 是非阻塞的 - javascript 引擎一直处于循环状态,检查注册调用是否已完成以及是否应处理其回调。这允许其操作是非阻塞的,从而允许单个 javascript 应用程序处理多个 XHR 长轮询请求。

    如果你能够使用 jQuery 来处理请求,它会用这个函数很好地包装 XHR:http://api.jquery.com/jQuery.ajax/。有了这个,您可以定义 20 秒的超时并立即处理它(以重新启动与您的服务器的连接)。

    除此之外 - 您可能希望考虑您的服务器堆栈以优化长轮询。确保您的 Web 服务器不会为每个请求生成一个线程(如 Apache 2.2) - 否则您将很快耗尽系统资源!如果您可以使用 node.js(它非常适合同时处理许多请求),请查看 socket.io 库作为服务器端和客户端解决方案 (http://socket.io/#home)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-29
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多