使用 Websocket 进行聊天应用

Using Websocket for chatting application

对于制作聊天应用程序,标准建议似乎是使用 Websocket 从服务器接收实时数据,而且这似乎是大多数人所做的。但我不明白的是 为什么生产聊天应用程序通过标准 AJAX 请求向服务器发送消息,而不是使用 WS.

Discord 和 Slack 的浏览器应用程序,尽管它们保持 WS 连接,但在发送聊天消息时,应用程序仅将 POST 发送到其端点之一。

不是生产聊天应用程序,但 ApolloClient 的 useSubscription 使用 WS 从服务器接收事件,但 mutate(我们将使用它来发送消息)作为标准 AJAX 发送。

对于聊天应用程序,如果我们与服务器有专用的 WS 连接,使用它发送任何数据不是 faster/more 高效吗?我认为通过标准 AJAX 发送数据(聊天应用程序的聊天消息)是有正当理由的,但是 SSE 不是 WS 上的 better/less 资源密集型选项吗?

wouldn't SSE be a better/less resource-intensive option over WS?

Server Sent Events 和 Web Sockets 都有非常相似的实现:它们在客户端和服务器之间打开一个专用套接字。因此,首先回答您的最后一个问题:它们对关键资源(该进程的套接字和服务器内存)的使用相同。

why sending data (chat message for a chatting app) is done through a standard AJAX

AJAX打开套接字(*),发送数据,服务器进程处理(推送到另一台服务器或写入数据库),然后可以关闭套接字,服务器有能力处理下一个传入请求。

*:使用HTTP/2多路复用,大多数时候可能已经有一个套接字就绪。

可以处理 1000 个客户端的 AJAX 推送的单个服务器在任何时候可能只能处理 50-100 个 SSE 或 Web 套接字连接。该比率取决于聊天消息的性质和可接受的延迟。

在一个极端情况下,如果您想 post 每次按键时都发生,并且让每个人都收到那个字符,并且大多数人大部分时间都在打字,AJAX 方法可能一次也只能处理 50-100 个客户。

另一个极端,如果聊天是完整的句子,直到用户按下 Enter 才发送,并且每个客户端每隔几分钟只写一次评论,那么单个服务器可能可以处理 10,000 个这类客户。

despite them maintaining WS connections, the apps just send POST to one of its endpoints when sending a chat message.

这很奇怪,不是吗:在理想的世界中,您会重新使用该连接。我认为这将归结为实际的工程问题。不同的部门处理不同的服务器,具有不同的可扩展性和延迟要求,可能还有不同的安全和备份策略。

换句话说,如果接收消息、将它们推送到数据库、轮询新消息并将它们发送出去,都由打开专用套接字的单个进程处理,那么所有代码​​都需要在一个大的、笨重的、难以维护的软件中。听起来还是挺简单的,10行代码?但是当它们为企业准备就绪时,具有身份验证、计费、遗留支持、垃圾邮件检测等。它们有数千行。

另一件事是专用套接字很难通过代理和移动设备进行维护。您需要 运行 一个 ajax 版本才能为这些客户提供可靠的服务。所以如果你无论如何都必须这样做,你还不如把它给大家使用,省去写两次代码。