服务器发送事件和 Ajax VS Websockets 和 Ajax

Server Sent Events and Ajax VS Websockets and Ajax

我正在创建一个应用程序 (Nuxtjs),但在确定向 API(expressjs) 发送数据和检索实时更新的好方法时遇到问题。看来我可以创建 "bi-di" 与协议 [Server Sent Events(SSE) 和 Axios 或 Websocket(WS)] 的连接。

这两种技术都适用于大多数浏览器,所以我认为没有必要添加额外的库,例如 socket.io - 对于那些没有当前浏览器的人(太糟糕了)。

该应用程序基于表单 data/clicks 的用户输入。然后其他用户 notified/updated 就会知道这些信息。在这一点上,用户可以响应并且链继续(基本聊天,如流程,一些信息将快速交换,而有些可能不会或永远不会)。

根据我的经验,用户流将更多地依赖于监听变化而不是实际更改数据 - 因此我正在考虑 SSE. 不幸的是,这两种协议都有其缺陷。

网络套接字:

  1. 并非所有组件都需要 WS 到 get/post 信息,因此以额外的服务器费用升级基本的 http 连接是没有意义的。因此,将需要 WS 以外的另一种方法 (Axios/SSR)。 Example: Checking to see if a user name exists
  2. 安全防火墙可能会阻止WS正常运行
  3. express-ws 使套接字在 API 端变得容易
  4. 我相信一个用户可以有超过 6 个并发连接(这可能有利也有弊)

服务器发送事件

  1. 似乎技术正在逐渐被 WS
  2. 所取代
  3. 监听事件似乎和监听事件一样简单 WS
  4. 无需升级连接,但必须在 expressjs API 中使用 node-spdy - 由于多路复用,这也可能是 WS 的一个很好的实现
  5. 更多的后端代码来设置 http2 并发出 SSEs(丑陋的代码以及 - 所以功能将被制作)
  6. 受限于 HTTP 限制(6 个并发连接),这是一个问题,因为用户可以轻松地将其最大化(即打开多个聊天 windows)

TLDR

应用程序将更加 "feed" 偶尔发布(可以由 Axios 处理)。但是,用户将收听多个 "feeds" 并且 HTTP 限制将成为一个问题。我不知道解决方案是什么,因为 SSE 似乎是更好的选择,因为我不需要不断地握手。如果这次握手真的无关紧要(从我读过的所有内容来看并非如此),那么 WS 可能是更好的选择。不幸的是,关于这两者有太多相互矛盾的信息。

想法?

我个人避免使用 websockets 作为 clientserver 之间的双向通信。

我尝试使用 sockets 到 broadcast data from server to users or a single user(socket),这样他们可以获得实时更新,但是对于从客户端到服务器的 post 请求,我倾向于使用 axios 或类似的东西,因为我不想将敏感数据(如访问密钥等)从 client 传递到 server

我的数据流是这样的

  1. 用户 post 使用 axiosSSE 或其他方式将数据发送到服务器
  2. 后端服务器执行它必须做的事情并通知套接字事件已发生
  3. Socket 服务器然后通知他必须通知谁

我使用套接字从客户端向服务器发送数据的问题是身份验证问题。从技术上讲,您不能通过套接字传递 任何客户端 javascript 不可用的内容,这意味着要验证操作,您必须通过网络套接字。这是一个有多种原因的问题——如果您的敏感数据可以使用客户端 js 访问,那么这里可以进行大量攻击。也有人可以监听 ws 和 client 之间的通信。这就是我使用 API 调用(axios 等)并将敏感数据存储到仅限 http 的 cookie 的原因。

因此,一旦服务器想要通知用户发生了某些事情,您可以通过告诉 websocket 服务器将数据发送给用户来轻松做到这一点。

您还想保持 API 服务器无状态,这意味着 API 中没有套接字。我只为 websocket 连接使用单独的服务器,我的 API 服务器和 websocket 服务器使用 redis 进行通信。 Pub/sub 是内部服务器通信和状态管理的一个非常巧妙的功能。

并回答有关多个连接的问题 - 您可以在 websocket 服务器和客户端之间使用单个连接,并使用通道广播数据。因此,一个频道用于通知提要,另一个频道用于故事提要等。

我希望这对你有意义。这个堆栈对我来说非常有用。

SSE、Web 套接字和普通 HTTP 请求(通过 AJAX 或 Fetch API)都是用于不同工作的不同工具。

上交所

  • 单向,从服务器到客户端。
  • 仅基于文本的数据。 (任何其他内容都必须序列化,即 JSON。)
  • 简单 API、广泛兼容、自动重新连接、具有用于赶上可能错过的事件的内置功能。

网络套接字

  • 双向。
  • 文本或二进制数据。
  • 要求您对发送的数据实现自己的含义。

标准 HTTP 请求

  • 客户端到服务器或服务器到客户端,但一次只有一个方向。
  • 文本或二进制数据。
  • 需要额外的努力来实时传输服务器到客户端的响应。
  • 从客户端到服务器的流式传输要求在请求时知道整个数据。 (例如,您不能执行事件流。)

如何决定:

  • 您是否正在将类似事件的数据从服务器流式传输到客户端?使用上证所。它是为此专门构建的,是一种非常简单的方法。
  • 您是否只向一个方向发送数据,并且不需要自发地通知客户某事?使用普通的 HTTP 请求。
  • 您需要使用长期建立的连接发送双向数据吗?使用网络套接字。

根据您的描述,听起来 SSE 或 Web Sockets 都适合您的用例。我可能倾向于 SSE,同时使用普通 HTTP 请求从客户端发送随机 API 调用。

I do not know what the solution would be because SSE seem like the better option as i do not need to continually handshake. If this handshake is truly inconsequential(which from everything i have read isn't the case) than WS is likely a better alternative.

请记住,您可以简单地为您的服务器配置 HTTP keep-alive,这一点没有实际意义。