WebSockets与SSE大对决:谁才是实时通信的王者?
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
在今天的博文中,我想深入探讨服务器发送事件(简称SSE)和WebSockets。这两种方法都是经过实战考验的数据交换方式。 我将首先简要介绍这两种工具的特性——它们是什么以及提供什么功能。然后,我会根据八个类别对它们进行比较,我认为这些类别对于现代系统来说最为关键。 与我之前比较REST和qRPC不同,我不会在每个类别中宣布任何胜者或授予分数。相反,在“总结”段落中,你会找到一个类似TL;DR的表格。该表格包含在上述领域中两种技术的关键差异。 与REST不同,SSE和WebSockets都更专注于特定的用例。在这种情况下,这两个概念的主要关注点是提供一个“实时”通信媒介。由于它们的特定关注点,它们不如REST流行,REST是一种更通用的、一刀切的工具。 不过,SSE和WebSockets都提供了一组有趣的可能性,为经典的REST方法解决复杂问题提供了轻微的更新。在我看来,最好了解它们并在我们的工具箱中为它们找到一席之地,因为有一天它们可能会派上用场。当你需要“实时”更新或你的应用程序需要更推送导向的方法时,它们可以为你提供一个更简单的解决方案。 简而言之,它是一种通信协议,通过使用一个持久的TCP连接在服务器和客户端之间提供双向通信。由于这一特性,我们不必不断从服务器拉取新数据。相反,数据在相关方之间“实时”交换。每个消息要么是二进制数据,要么是Unicode文本。 该协议于2011年由IETF以RFC 6455的形式标准化。WebSocket协议与HTTP不同,但两者都位于OSI模型的第七层,并依赖第四层的TCP。 该协议有一套独特的前缀,类似于HTTP的http和https前缀: 此外,从安全站点(https)不应打开非安全的WebSocket连接(ws)。类似地,从非安全站点(http)不应打开安全的WebSocket连接(wss)。 另一方面,WebSocket按设计在HTTP端口443和80上工作,并支持HTTP概念,如代理和中间件。此外,WebSocket握手使用HTTP升级头来将协议从HTTP升级到WebSocket。 WebSocket作为一个协议的最大缺点是安全性。WebSocket不受同源策略的限制,这可能使类似CSRF的攻击更容易。 SSE是一种允许网络服务器向网页发送更新的技术。它是HTML 5规范的一部分,与WebSockets类似,使用一个持久的HTTP连接来“实时”发送数据。在概念层面上,它是一种相当古老的技术,其理论背景可以追溯到2004年。2006年,Opera团队首次尝试实现SSE。 SSE得到了大多数现代浏览器的支持——Microsoft Edge于2020年1月添加了SSE支持。它还可以充分利用HTTP/2,这实际上消除了SSE的一个最大问题,即实际上消除了HTTP/1.1所施加的连接限制。 根据规范,服务器发送事件有两个基本构建块: 根据规范,事件可以携带任意文本数据,一个可选的ID,并由换行符分隔。它们甚至有其独特的MIME类型:text/event-stream。 此外,SSE提供了两个非常有趣的特性: 可能是这两种技术之间最大的区别在于它们的通信方式。 我会在接下来的段落中描述所有这些领域以及更多内容。此外,在所有情况下使用WebSocket可能是一个重大过度,基于SSE的解决方案可能更简单易行。 这里出现了这两种技术之间的另一个重大区别。 在SSE的情况下,使用HTTP/2解决了SSE的一个主要问题——最大并行连接限制。HTTP/1.1根据其规范限制并行连接的数量。 这种行为可能导致一个称为头部阻塞的问题。HTTP/2通过引入多路复用解决了这个问题,从而在应用层解决了头部阻塞问题。然而,TCP级别的头部阻塞仍然可能发生。 至于WebSocket协议,我在上面几行中已经详细提及。在这里,我只会重申最重要的几点。该协议与经典的HTTP有些不同,尽管使用HTTP升级头来初始化WebSocket连接并有效地更改通信协议。 尽管如此,它还以TCP协议为基础,并且与HTTP完全兼容。WebSocket协议最大的缺点是其安全性。 一般来说,设置基于SSE的集成比其WebSocket对应物更简单。其背后最重要的原因是特定技术所利用的通信性质。 SSE的单向通信方式及其推送模型在概念层面上使其更简单。结合自动重连和流连续性支持,SSE开箱即用,减少了我们需要处理的事情的数量。 在WebSocket的情况下,事情变得有点复杂。首先,我们需要处理从HTTP到WebSocket协议的连接升级。尽管这是最简单的事情之一,但仍然是我们需要记住的另一件事。 第二个问题是WebSocket的双向性质。我们必须管理特定连接的状态,并处理在处理消息时发生的所有可能的异常。例如,如果服务器端处理其中一个消息时抛出异常,我们该怎么办? 接下来是处理重连的问题,这在WebSocket的情况下需要我们自己处理。 还存在影响这两种技术的问题——长连接。 这两种技术都需要维护长连接以发送持续的事件流。 在大规模管理这些连接可能是一个挑战,因为我们可能很快耗尽资源。此外,它们可能需要特殊配置,如延长超时时间,并且更容易受到任何网络连接问题的影响。 对于SSE来说,安全性没有什么特别之处,因为它使用HTTP协议作为传输介质。所有标准的HTTP优点和缺点都适用于SSE,非常简单。 另一方面,安全性是WebSocket协议作为一个整体最大的缺点之一。首先,没有同源策略,因此我们可以通过WebSocket连接到任何地方,没有任何限制。 甚至有一种专门针对这种漏洞的攻击类型,即跨源WebSocket劫持。如果你想要深入了解更多关于同源策略和WebSocket的内容,这里有一篇文章可能会引起你的兴趣。除此之外,WebSocket协议本身没有特定的安全漏洞。 我会说,在这两种情况下,所有标准和最佳安全实践都适用,因此在实现解决方案时要小心谨慎。 我会说,在性能方面,这两种技术可以说是不相上下。这两种技术本身都没有理论性能限制。 然而,我会说SSE在每秒发送的消息数量方面可能更快,因为它遵循一种类似“发送后即忘”的原则。WebSocket还需要处理来自客户端的响应。 唯一可能影响两者性能的因素是我们应用程序中使用的底层客户端及其实现。检查、阅读文档、运行自定义压力测试,你可能会对所使用的工具或整个系统获得非常有趣的见解。 消息结构可能是协议之间另一个最重要的区别。 正如我在上面提到的,SSE是一种纯文本协议。我们可以发送不同格式和内容的消息,但最终所有内容都以UTF-8编码的文本形式结束。不允许复杂的格式或二进制数据。 另一方面,WebSocket可以处理文本和二进制消息。这使我们能够发送图像、音频或只是普通文件。只是要记住,处理文件可能会有显著的开销。 在这方面,这两种技术处于非常相似的阶段。无论是SSE还是WebSockets,都缺少用于自动化测试的专用工具。然而,你可以相对容易地使用Postman和集合来实现类似功能。 Postman支持SSE和WebSockets。通过使用Postman集合的一些魔法,你可以准备一组测试来验证端点的正确性。 对于性能测试,你可以选择JMeter或Gatling。据我所知,这两个工具是整体性能测试中最成熟的工具。当然,它们也支持SSE(JMeter,Gatling)和WebSockets(JMeter,Gatling)。 还有其他工具如sse-perf(仅限SSE),Testable或k6(仅限WebSockets)。 在所有这些工具中,我个人会推荐Gatling或k6。两者似乎都有最好的用户体验,并且最接近生产环境。 在某种程度上,没有专门用于为SSE或WebSockets生成文档的工具。另一方面,有一个名为AsyncAPI的工具可以以这种方式使用,适用于这两个概念。 不幸的是,OpenAPI似乎不支持SSE或WebSockets。 如我所承诺的,总结将快速而简单——请参阅下方表格。 我认为上述表格是对主题和整篇文章的一个相当简洁的总结。 最重要的区别是通信方向,因为它决定了特定技术的可能用例。这将对选择一个而不是另一个产生最大的影响。 消息结构在选择特定通信方式时也可能是一个非常重要的类别。仅允许纯文本消息对于服务器发送事件来说是一个非常显著的缺点。 阅读原文:原文链接 该文章在 2025/5/29 10:59:07 编辑过 |
关键字查询
相关文章
正在查询... |