我一直在远离我在PHP/MySQL中的舒适区,因为语法/封装/过程性的东西可能会令人沮丧.

上周,我开始玩游戏,并按照一些教程使用Node.js/Socket.IO创建实时聊天应用程序.到目前为止,我还没有用WebSocket做过任何事情,它们看起来非常酷——服务器和客户端之间的即时通信非常棒.

现在,请原谅我在这里缺乏理解,但HTTP的设置是为了让客户机和服务器之间的连接保持打开状态——我对Comet的基本理解是,它通过从不终止写入流,只发送NUL字节来强制连接保持打开状态.这听起来...服务器密集型.

那么WebSocket是如何工作的呢?如果我的聊天应用上同时有几百人,服务器不会过载吗?当我在服务器上使用PHP/MySQL时,服务器一次只处理一个请求——如果我使用AJAX和轮询,比如说,每一秒钟,我想它会迅速升级,因为一分钟会有数千个请求.

我的问题是,WebSocket是否适用于大型应用程序?如果没有真正高带宽的服务器,它是否实用?

我想这可以归结为:频繁间隔的AJAX轮询、Comet和WebSocket之间是否存在显著的服务器负载/用户体验差异?

谢谢

推荐答案

关于WebSocket通常是如何工作的,比如herehere,有很多好的概述网站可以阅读.

简而言之,它们通过某种类型的HTTP请求启动连接,然后在客户端和服务器之间建立直接的TCP双向连接.

维护客户机的开放式套接字需要一些服务器开销,因此,如果您预期同时会有上万个这样的套接字,那么您必须确保您的服务器基础设施能够达到这样的规模.CPU负载只与在任何给定时间有多少插槽处于繁忙状态成正比,因为空闲插槽不占用任何CPU.

使用WebSocket是否需要服务器成本?

这真的取决于你把它和什么做比较.WebSocket通常用于服务器需要能够在数据可用时向客户端发送数据(通常称为"服务器推送").使用连续连接的webSocket的通常替代方法是让客户端反复轮询,反复询问服务器是否有任何新内容.如果您将webSocket与重复的客户端轮询进行比较,那么webSocket通常是非常非常高效的,并且使用webSocket可以比使用频繁轮询的客户端更高地扩展服务器.

服务器可以正确配置为支持数十万个同时(且大部分是空闲)的webSocket连接,这样服务器的可扩展性限制就受到您发送到所有这些连接的客户端的流量的限制.如果你每隔几秒钟就向一个客户端发送数据,并且你有数十万个已连接的客户端,那么使用任何技术都需要大量的服务器马力(和带宽),而WebSocket可能仍然比任何竞争技术都要好.但是,如果与webSocket连接的客户机大多处于空闲状态,并且数据只是偶尔发送给它们,那么webSocket实现可以进行大规模高效扩展.

以下是关于该主题的其他参考资料:

Websockets and scalability

websocket vs rest API for real time data?

Websocket vs REST when sending data to server

Ajax vs Socket.io

Why to use websocket and what is the advantage of using it?

HTML5 WebSocket: A Quantum Leap in Scalability for the Web

Push notification | is websocket mandatory?


Comet库试图支持类似WebSocket的接口,即使没有直接的WebSocket支持.当它试图通过保持一个开放的HTTP连接来模拟一个双向TCP套接字时,一些低效的黑客开始出现在这里.如果您使用的是真正的WebSocket,这不是问题.

Node.js相关问答推荐

Node.js promise 循环中的所有多个API调用

如果非SQL函数在事务内部运行失败,PG-Promise事务会回滚吗?

获取页面大小为10的所有文章,每篇文章填充一些所需的用户信息

如何防止Socket-io实例化React/Next.js中的两个套接字(当前在服务器*和*客户端实例化)

如何在nodejs中打印pdf

几个 lambda 共有的函数

我需要聚合两个 MongoDB 集合

如何修复我的 NodeJS SSE 写入函数以在后续调用中更新 HTML?

使用更新版本仍然找到包@angular/fire但不支持原理图

使用 create-expo-app 时如何更改 webpack-config.js 中的哈希函数?

后端位于 Docker 容器中时的 SvelteKit SSR fetch()

AWS EC2 npm install 突然很慢

如何在 Nest.js 中使用查询参数?

在 PassportJS 中使用多种本地策略

分块 WebSocket 传输

socket.io 发出回调合适吗?

Sequelize 基于关联的查找

为什么我会收到错误:解决方法指定过多?

Puppeteer:如何提交表单?

nodejs v10.3.0 的 gulp 任务问题:src\node_contextify.cc:629: Assertion `args[1]->IsString()' failed