JavaScript:每个客户端两个连接?

3
我正在开发一个应用程序,实现长轮询功能,因为我希望用户能够在通知到达时立即收到提醒。我已经完成了这部分的工作,但还需要扩展此功能,使用一个javascript函数每20秒向服务器发送一个“心跳”信号。
我的问题是:如何在不完全中断代码的情况下进行倒计时(以便在计数时仍然执行其他javascript代码),是否有一种方法可以使用第二个连接来实现?因为我不希望当发送“心跳”信号给用户时,长轮询被中断。
有什么建议吗?

如何使用一个超时时间为20000毫秒的计时器,在服务器异步请求完成后,再休眠20000毫秒呢? - user497849
如果客户端中断了HTTP连接,您的服务器肯定会注册此事件。您应该能够捕获此事件。 - bennedich
@bennedich:我认为在连接关闭时不会生成事件,我不知道服务器如何知道它。 - user393964
@DorinDuminica:我不能让它休眠20000毫秒,因为异步连接应该始终可用。 - user393964
@Sled:好的。setTimeoutsetInterval应该能够在不干扰其他代码的情况下定期发送异步请求(XMLHttpRequest)。 - bennedich
不会中断我的长轮询连接吧?出于某种原因,我认为JS一次只使用一个连接。 - user393964
3个回答

6

尽管下面的讨论内容相对较旧,但它表明浏览器允许在任意时刻通过XMLHttpRequest建立多个连接。

流行浏览器允许同时进行多少个AJAX(XmlHTTPRequest)请求?

如果你有一个长轮询会话,无论是使用XMLHttpRequest还是其他任何实现comet的方式,都可以在setInterval或setTimeout函数中创建另一个到同一服务器的请求,直到达到浏览器所施加的有限制的最大值。所有您需要确保的是在XHR构造中包含异步标志:

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

4

使用 setInterval(yourHearbeatFunction, 20000),它不会锁定JavaScript执行线程。因此,长轮询请求将在到达时立即处理。


问题在于,如果单个心跳需要超过20秒才能完成,您将开始堆叠打开的请求,这将减慢浏览器的速度。由于超时时间为20秒,因此这很可能不是问题,但如果超时时间更短,则可能会出现问题。 - Ariel

1

你不需要为了你想要实现的目标而维护多个连接。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)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接