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

时间:2019-11-06 23:48:01

标签: express websocket server-sent-events ws

我正在创建一个应用程序(Nuxtjs),无法确定一种将数据发送到API(expressjs)并检索实时更新的好方法。看来我可以使用两个协议[服务器发送事件(SSEAxios或Websocket(WS)来创建“双向”连接。

这两种技术都适用于大多数浏览器,因此我认为无需添加其他库,例如socket.io-对于那些没有当前浏览器的人(太糟糕了)。

该应用程序基于表单数据/点击的用户输入。然后,其他用户将收到该信息的通知/更新。在这一点上,用户可以做出响应并且链条继续(基本的聊天之类的信息流将迅速交换,而某些消息则可能永远不会交换)。

根据我的经验,用户流将更多地依赖于侦听更改而不是实际更改数据-因此,我为什么考虑使用SSE不幸的是,这两种协议都有其缺陷。

Websockets

  1. 并非所有组件都需要WS来获取/发布信息,因此,在不增加服务器费用的情况下升级基本的http连接是没有意义的。因此,将需要除WS之外的其他方法(Axios/SSR)。 Example: Checking to see if a user name exists
  2. 安全防火墙可能阻止WS正常运行
  3. express-ws使API端的套接字变得容易
  4. 我相信您一个用户可以有6个以上的并发连接(可能是优缺点)

服务器发送事件

  1. 似乎这项技术正在逐渐淡化,取而代之的是WS
  2. 听事件似乎和听WS的事件一样容易
  3. 无需升级连接,但必须在node-spdy API中使用expressjs-由于多路复用,这对于WS也是一个很好的实现方式
  4. 仅需少量后端代码即可设置http2并发出SSE s(同样丑陋的代码-这样就可以创建函数了)
  5. 受限于HTTP限制(6个并发连接),这是一个问题,因为用户可以轻松地将其最大化(即,打开多个聊天窗口)

TLDR

该应用程序将更倾向于“供稿”,并偶尔发布(可由Axios处理)。但是,用户将收听多个“提要”,并且HTTP限制将成为问题。我不知道解决方案是什么,因为SSE似乎是更好的选择,因为我不需要不断地握手。如果这种握手确实是无关紧要的(从我所读的内容来看并非如此),那么比WS可能是更好的选择。不幸的是,关于这两者的信息太多了。

有想法吗?

2 个答案:

答案 0 :(得分:0)

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

SSE

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

Web套接字

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

标准HTTP请求

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

如何决定:

  • 您是否正在将类似事件的数据从服务器流传输到客户端?使用SSE。它是为此目的而专门设计的,是一种死路一条简单的方法。
  • 您是否仅在一个方向上发送数据,并且不需要自发地通知客户某些信息?使用普通的HTTP请求。
  • 是否需要通过长期建立的连接发送双向数据?使用Web套接字。

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

  

我不知道解决方案是什么,因为SSE似乎是更好的选择,因为我不需要不断地握手。如果这种握手确实是无关紧要的(从我所读的内容来看并非如此),那么WS可能是一个更好的选择。

请记住,您可以简单地使用HTTP保持活动配置服务器,这很重要。

答案 1 :(得分:-2)

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

我尝试使用broadcast data from server to users or a single user(socket)套接字,以便它们可以实时更新,但是对于从客户端到服务器的发布请求,我倾向于使用axios或类似的东西,因为我不想传递从clientserver的敏感数据(如访问密钥等)。

我的数据流类似于

  1. 用户使用axiosSSE或其他任何方式将数据发布到服务器
  2. 后端服务器执行其操作并通知套接字已发生事件
  3. 套接字服务器然后通知他必须执行的操作

我使用套接字将数据从客户端发送到服务器的问题是身份验证问题。从技术上讲,您无法通过套接字传递客户端JavaScript无法使用的任何内容,这意味着要验证操作,您将必须通过网络套接字发送敏感信息。这是一个有多个原因的问题-如果可以使用客户端js访问敏感数据,则可以在此处进行大量攻击。也有人可以收听ws和客户端之间的通信。这就是为什么我使用API​​调用(axios等)并将敏感数据存储到仅HTTP cookie中的原因。

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

您还希望使API服务器保持无状态,这意味着您的API中没有套接字。我仅将单独的服务器用于websocket连接,而我的API服务器和websocket服务器使用Redis进行通信。 Pub / sub是用于内部服务器通信和状态管理的非常整洁的功能。

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

我希望这对您有意义。这个堆栈对我来说真的很好。