原文链接:https://www.pubnub.com/guides/long-polling/

什么是长轮询?

长轮询用于实时 Web 应用程序,以实现客户端和 Web 服务器之间近乎即时的通信。它在实时更新至关重要的聊天和消息应用程序中特别有用。

在传统的HTTP通信中,客户端向服务器发送新请求并等待响应。这称为短轮询。然而,在实时场景中,短轮询可能效率不高,因为它需要频繁向服务器请求,导致不必要的网络开销和增加延迟。

另一方面,长轮询通过在新数据可用之前保持请求长时间打开来提高效率。服务器保持请求打开并等待,直到有新信息发送回客户端。一旦服务器有新数据,它就会响应客户端,然后客户端可以处理数据并发起新的长轮询请求。

通过维持客户端和服务器之间的长期连接,长轮询减少了请求数量,最大限度地减少了延迟,并提高了实时通信。这使得它非常适合需要有效技术来构建可扩展和响应式聊天和消息传递应用程序以及其他利用游戏等实时数据的应用程序的用例。

长轮询如何工作?

长轮询是一种用于实时通信的技术,用于在客户端和服务器之间实现近乎即时的消息传递。它在构建低延迟和实时更新至关重要的聊天和消息传递应用程序时特别有用。

传统上,Web 浏览器使用基于拉取的方法从服务器获取数据。客户端向服务器发送请求,服务器以请求的数据进行响应。这种方法称为短轮询,可能会造成通信延迟,因为客户端必须重复发送请求来检查更新。

另一方面,长轮询是一种基于推送的方法,允许服务器在更新可用时立即向客户端发送更新。它的工作原理如下:

  1. 客户端向服务器发起请求,通常通过 HTTP 请求。
  2. 服务器不会立即响应,而是将请求保持打开状态,从而保持连接处于活动状态。
  3. 如果没有新数据可用,服务器将等待,直到有数据要发回。
  4. 一旦服务器有新的数据或者发生预定义的超时,它就会用最新的信息响应客户端。
  5. 客户端收到响应后,立即向服务器发送另一个请求以维持连接。
  6. 这种发送请求和接收响应的循环持续进行,确保实时更新。

长轮询通过长时间保持请求-响应周期打开来有效地模拟客户端和服务器之间的实时连接。它允许服务器在更新可用时立即将更新推送到客户端,并且无需客户端重复检查更新。

使用什么技术来实现长轮询?

长轮询是一种实现客户端和服务器之间实时通信的技术。它通常用于即时更新至关重要的聊天和消息传递应用程序。可以使用多种技术来实现长轮询,每种技术都有优点和注意事项。让我们探讨一些用于实现长轮询的常用技术。

HTTP 长轮询

这是实现长轮询的最基本、最广泛使用的方法。它利用 HTTP 协议建立并维护客户端和服务器之间的长期连接。客户端向服务器发送请求,服务器将请求保持打开状态,直到有新数据可用或达到某个超时。一旦有新数据可用,服务器就会用更新的信息进行响应,客户端立即发送另一个请求以继续循环。这种方法易于实现,不需要特殊的服务器端技术。

网络套接字:

WebSocket 是一种全双工通信协议,可通过单个长期连接在客户端和服务器之间实现实时通信。它提供了比长轮询更高效、低延迟的替代方案。 WebSocket 支持双向数据流,允许客户端和服务器异步发送消息。它消除了频繁的 HTTP 请求并减少了网络开销。 WebSocket 非常适合需要即时更新和实时交互的应用程序。

服务器发送的事件 (SSE):

SSE 是一种单向通信技术,允许服务器通过单个长期 HTTP 连接将数据推送到客户端。通过SSE,服务器可以向客户端发送多个更新,而不需要客户端不断地发出请求。服务器启动连接并以一系列事件的形式发送数据。客户端接收这些事件并可以根据需要进行处理。

在选择在应用程序中实现长轮询的技术时,需要考虑以下几个因素:

  • 可扩展性:确保所选技术可以处理大量并发连接,并且可以随着用户群的增长而扩展。 WebSocket 和 SSE 通常比基于 HTTP 的长轮询更具可扩展性,因为它们允许更有效地使用服务器资源。
  • 安全性:考虑所选技术的安全影响。 WebSocket 和 SSE 可以使用SSL/TLS等加密协议进行保护,从而确保数据隐私和完整性。基于 HTTP 的长轮询也可以得到保护,但可能需要额外的身份验证和访问控制措施。
  • 浏览器支持:检查所选技术的浏览器兼容性。 WebSocket 和 SSE 比基于 HTTP 的长轮询具有更好的浏览器支持,这可能需要额外的技术或针对旧浏览器的后备选项。
  • 实施复杂性:评估所选技术的实施和维护难易程度。基于 HTTP 的长轮询相对简单,而 WebSocket 和 SSE 可能需要更高级的知识和基础设施。考虑开发团队可用的专业知识水平以及实施和维护所选技术所需的资源。

长轮询与 WebSockets

长轮询和 WebSocket是在客户端(例如 Web 浏览器)和服务器之间实现实时连接的技术。尽管它们的目的相似,但两者存在显着差异。

长轮询是一种技术,客户端向 Web 服务器发出请求,服务器保持连接打开,直到有新数据要发回。如果服务器有新数据可用,则可以立即响应,或者在发送空响应之前等待指定的超时时间。无论哪种情况,客户端一旦收到响应,就会立即向服务器发出另一个请求以建立新连接。此过程不断重复,允许服务器在更新可用时立即将更新推送到客户端。

另一方面,WebSockets 在客户端和服务器之间提供持久的双向通信通道。与长轮询不同的是,长轮询会为每个请求建立一个新连接,而 WebSocket 连接只会建立一次并无限期地保持打开状态。这允许双向实时、低延迟通信。服务器可以随时向客户端推送数据,客户端也可以不等待响应就向服务器发送数据。

长轮询和 Web Sockets 之间的相似之处:

1.实时更新:长轮询和WebSockets都可以实现服务器和客户端之间的实时通信,允许即时更新,无需连续轮询或刷新。

  1. 减少服务器负载:这两种技术都通过仅在数据可用时发送数据来最大程度地减少不必要的请求,从而减少服务器负载并提高可扩展性。
  2. 广泛的语言和框架支持:许多流行的编程语言和框架都支持长轮询和WebSocket,使不同生态系统的开发人员都可以使用它们。

长轮询和 Web Sockets 之间的区别:

1.延迟:长轮询会引入延迟,因为服务器发送响应和客户端接收响应之间存在延迟。 WebSocket 提供双向、低延迟通信,从而实现更快的实时功能。

2.资源消耗:长轮询需要服务器与每个客户端保持开放的连接,可能会导致资源消耗并限制并发连接数。然而,WebSockets 使用持久连接,减少了总体资源消耗。

  1. 可扩展性:长轮询需要长时间保持连接打开,这可能会给服务器的水平扩展带来挑战。凭借持久连接,WebSocket 可以实现更好的可扩展性,因为它们不需要很多打开的连接。

长轮询和 WebSocket 都提供实时更新并减少服务器负载,但它们在延迟、资源消耗和可扩展性方面有所不同。 Web 套接字提供更快的双向通信,同时减少资源消耗,使其适合需要低延迟和高可扩展性的应用程序。另一方面,当低延迟并不重要且并发连接数相对较小时,长轮询可能是一个不错的选择。开发人员在为实时聊天和消息应用程序选择两种技术时应考虑这些因素。

长轮询与服务器发送事件 (SSE)

SSE在简单性和易于实现方面与长轮询类似,但它提供了一种更高效、更标准化的方式来实现服务器到客户端的通信。让我们看看这两种技术之间的一些其他相似点和不同点。

长轮询和 SSE 的相似之处:

  1. 实时更新:长轮询和SSE都可以实现服务器和客户端之间的实时通信,允许即时更新,无需持续轮询或刷新。
  2. 减少服务器负载:这两种技术都通过仅在数据可用时发送数据来最大程度地减少不必要的请求,从而减少服务器负载并提高可扩展性。
  3. 广泛的语言和框架支持:许多流行的编程语言和框架都支持长轮询和SSE,使不同生态系统的开发人员可以使用它们。

长轮询和SSE的区别:

  1. 延迟:长轮询会引入延迟,因为服务器发送响应和客户端接收响应之间存在延迟。另一方面,SSE提供从服务器到客户端的连续数据流,减少延迟并提高实时能力。
  2. 资源消耗:长轮询要求服务器与每个客户端保持打开的连接,可能会导致资源消耗并限制并发连接数。然而,SSE 使用单个长期连接,减少了总体资源消耗。
  3. 可扩展性:长轮询需要长时间保持连接打开,这可能会给服务器的水平扩展带来挑战。由于每个客户端只有一个连接,SSE 不需要许多打开的连接,因此可以实现更好的可扩展性。

如何优化长轮询?

长轮询用于实时聊天和消息传递应用程序,以提供近乎即时的客户端更新。但是,如果优化不当,它可能会占用资源并导致可扩展性问题。以下是可用于优化长轮询以获得更好性能和可扩展性的几种技术。

**批量响应:**不是为每个请求发送响应,而是[将多个更新一起批处理](https://developers.google.com/classroom/best-practices/batch#:~:text=separate HTTP request.-,Response to a batch request,same order as the requests.)并在单个响应中发送它们。这减少了 HTTP 请求的数量并有助于最大限度地减少开销。

**压缩:**在通过网络发送数据之前对其进行压缩可以显着减少有效负载大小,从而加快传输速度并降低带宽消耗。Gzip 压缩等技术可用于实现此目的。

**缓存:**实现缓存层可以帮助减少数据库或其他数据源的负载。通过缓存频繁请求的数据,后续请求可以从缓存本身得到服务,从而减少响应时间并提高可扩展性。

**连接池:**维护一个可重用连接池,而不是为每个请求创建一个新连接,可以提高长轮询机制的效率。这消除了为每个请求建立新连接的开销,从而获得更好的性能。

**节流和速率限制:**实施节流和速率限制机制可以防止过多的请求压垮服务器。这可确保公平的资源分配并防止滥用,从而提高性能和可扩展性。

负载平衡**:**使用负载平衡技术在多个服务器之间分配传入请求可以帮助分配负载并防止任何单个服务器不堪重负。这提高了长轮询系统的整体性能和可扩展性。

**监控和优化:**定期监控长轮询系统的性能并识别任何瓶颈或改进领域可以帮助优化系统以获得更好的性能和可扩展性。分析、负载测试和性能调整等技术可用于识别和解决任何性能问题。

**异步(Async)处理:**将耗时的任务卸载给异步进程或后台工作人员可以帮助释放资源并提高长轮询系统的响应能力。您可以通过消息队列、工作进程或分布式计算来获取此信息。

**连接超时:**实施适当的连接超时有助于防止空闲连接消耗不必要的资源。通过在一段时间不活动后关闭空闲连接,系统可以为其他客户端释放资源并提高可扩展性。

**可扩展的基础设施:**确保底层基础设施可扩展并且能够处理预期的负载对于优化长轮询至关重要。这可能涉及使用云计算、自动扩展或容器化等技术来根据需求动态分配资源。

哪些编程语言与长轮询兼容?

多种编程语言与在实时聊天和消息传递应用程序中实现长轮询兼容。这里有一些例子:

  1. JavaScript:长轮询通常与JavaScript结合使用,允许无缝的客户端实现。React、Angular 和Vue.js等JavaScript框架提供了可简化应用程序中长轮询实现的库和工具。
  2. PHP:PHP是一种流行的服务器端语言,经常用于 Web 开发。它提供的功能和库使开发人员能够有效地实现长轮询。例如,PHP 框架 Laravel 通过其事件广播系统提供对长轮询的支持。
  3. Python:Python是另一种通用语言,可用于实现长轮询。 Django 和 Flask 等 Python 框架提供了使用长轮询技术构建实时应用程序的工具和库。
  4. Ruby:Ruby是一种动态的、面向对象的编程语言,非常适合 Web 开发。流行的 Web 框架Ruby on Rails支持通过各种库和扩展进行长轮询。
  5. Java:Java是企业开发中广泛使用的语言,提供长轮询的支持。 Spring 和 Java EE 等 Java 框架提供了用于在实时应用程序中实现长轮询的库和工具。
  6. .NET/C#:. NET 框架及其编程语言 C#通常用于构建 Web 应用程序。它提供了 ASP.NET SignalR等库和框架,可简化长轮询技术的实现。

这些只是支持长轮询的编程语言的几个示例。许多其他语言和框架也可以在实时聊天和消息应用程序中实现长轮询。

在选择用于实现长轮询的编程语言时,需要考虑几个因素。首先,考虑您的应用程序的具体要求并选择最适合这些要求的语言。考虑后端的可扩展性、性能和易于实施性。

此外,请考虑围绕编程语言的社区和生态系统。强大而活跃的社区可以提供支持、教程、文档和资源,使您的应用程序中的长轮询实现变得更加容易。

长轮询在实时应用中如何使用?

长轮询的主要优点之一是其提供实时更新的效率。最大限度地减少客户端发送的请求数量可显着降低网络延迟并提高整体性能。此外,它允许服务器立即向客户端推送更新,确保消息和通知及时传递。

此外,长轮询有利于实时应用程序的可扩展性。减少打开连接的数量使服务器能够处理更多并发客户端。这在用户数量不断波动的聊天和消息传递应用程序中尤其重要。

长轮询有助于节省系统资源。使用传统的轮询,每个请求都需要服务器处理和响应,即使没有更新。这种持续的处理可能会使服务器资源紧张并对性能产生负面影响。相反,长轮询仅在有新数据可用或发生超时时触发服务器处理。这最大限度地减少了系统资源的压力,并实现了更好的可扩展性和可靠性。

然而,实施长轮询也会带来一些挑战。一项挑战是有效管理服务器资源。由于长轮询涉及长时间保持连接打开,因此处理多个并发连接需要大量服务器资源。这可以通过使用云计算、自动扩展或容器化等技术来根据需求动态分配资源来解决。通过根据活动连接数量自动扩展或缩减资源,开发人员可以确保服务器能够有效地处理预期负载。

另一个挑战是处理超时和连接失败。在长轮询中,服务器保持请求打开,直到有新数据可用或发生超时。如果发生超时,服务器必须妥善处理并关闭连接以释放资源。此外,如果连接失败,服务器应该能够检测到它并适当地处理重新连接尝试。通过实现强大的错误处理和连接管理机制,开发人员可以确保实时应用程序中长轮询的可靠性。

在实时应用程序中实现长轮询时,安全性是另一个重要的考虑因素。由于长轮询涉及维护客户端和服务器之间的持久连接,因此保护这些连接以保护敏感数据至关重要。实施安全套接字层 (SSL) 或传输层安全 (TLS) 协议可以帮助加密通过长轮询连接传输的数据,并防止窃听或未经授权的访问。