前言
Fastify 是一款由 Node.js 社区发布的快速、低开销且高度可定制的 Web 框架,而 WebSocket 是 HTML5 开始就支持的协议,能够实现客户端和服务器之间的实时通讯。此篇文章将介绍如何在 Fastify 中使用 WebSocket,以及一些有关性能和安全方面的指导。
WebSocket 基础概述
WebSocket 协议是一种基于 TCP 的全双工通信协议,通过一次握手的方式建立客户端和服务器之间的连接,从而实现实时通讯。与传统的 HTTP 通信相比,WebSocket 可在客户端和服务器之间实现低延迟、高吞吐量的通讯。其主要特点包括以下几个方面:
- 持久连接:WebSocket 建立的连接一旦建立,可以保持持久连接状态,并且在双方关闭连接之前不会断开。
- 全双工通讯:WebSocket 支持双向通讯,客户端和服务器可以同时进行数据传输。
- 低延迟、高吞吐量:由于建立的是持久连接,并且是全双工通讯,因此数据的传输效率更高,延迟更低。
如何在 Fastify 中使用 WebSocket
Fastify 提供了一个基于 ws 模块的插件 fastify-websocket
,使得在 Fastify 中使用 WebSocket 非常便捷。
安装
首先要确保你已经安装了 Fastify 和 WebSocket,接着执行以下命令进行安装:
npm install fastify-websocket
实现
在 Fastify 中启用 WebSocket 简单易行,只需要几行代码:
-- -------------------- ---- ------- ----- ------- - --------------------- ----- --------- - -------------- ----- ------------ - --- ------------------ --------- ---- --- ---------------------------------------------- - ------- ---------------------------------------------- --- ---------------------- - ---------- ---- -- ------------ -------- -- - ------------------------------- ------- -- - --------------------- ------- ---------- ---- - ---------- -- -- --------- --- -- ---- ------- -- ------ ---------------------------- ----------- ---展开代码
以上代码中,我们启用了 Fastify 的 WebSocket 插件,并使用 websocket: true
来指定这是一个 WebSocket 请求,使用 connection.socket.on
来监听客户端发送的消息,并使用 connection.socket.send
来向客户端发送消息。
值得注意的是,以上代码中我们使用了 socketServer.handleUpgrade
来处理 WebSockets 的 upgrade 请求,这意味着,我们不仅可以在 HTTP 上使用 Fastify,也可以使用 HTTPS。当 Fastify 在加密的 HTTP 安全通道(HTTPS)下运行时,我们需要手动处理 WebSocket 的 upgrade 请求。
安全方面
在使用 WebSocket 时,由于它不像 HTTP 协议具备内置的安全机制,因此需要我们自己处理一些安全问题,以保证 WebSocket 通讯过程中不被攻击和窃听。
- 启用 SSL/TLS
使用 SSL/TLS 协议可以加密客户端和服务器之间的通讯流量,防止信息泄漏和流量劫持。如果你运行的是 HTTPS 网站,那么你已经启用了 SSL/TLS,WebSocket 将自动使用它。
- HTTP 头 Origin 检验
在建立 WebSocket 连接时,需要通过 Origin 标头来验证该连接是否来自正确的源。这将防止 XSRF 攻击、会话劫持等常见的 Web 安全漏洞。
在 Fastify WebSocket 插件中,我们可以使用 connection.socket.upgradeReq.headers.origin
来获取来自客户端的原始标头,以进行安全检查。
性能方面
如果你想使用 WebSocket,以实现更快的实时通讯,在性能方面一些关键的提示也是非常有用的。
- 内存爆炸问题
在使用 WebSocket 时,可能会出现内存占用过高的情况,因为每个客户端都会创建一个独立的 WebSocket 连接。为了解决这个问题,我们可以使用 "ws"
中的 ping
和 pong
消息机制,来进行空闲连接的清除和重试。
const socketServer = new WebSocket.Server({ noServer: true, clientTracking: true, pingInterval: 10000, pingTimeout: 60000, });
以上代码中,我们将 pingInterval 设置为 10 秒,表示客户端连接在 6 秒内没有接收到 ping 或 pong 时将被自动中断。
- 只广播必要数据
如果你的应用程序使用了广播连接,你可能只需要发送频繁变化的数据。在 Broadcast/Acknowledgment 模式下,客户端应该只接收必要的更新,而不是完整的应用程序状态。
示例代码
-- -------------------- ---- ------- ----- ------- - --------------------- ----- --------- - -------------- ----- ------------ - --- ------------------ --------- ---- --- ---------------------------------------------- - ------- ---------------------------------------------- --- ---------------------- - ---------- ---- -- ------------ -------- -- - ------------------------------- ------- -- - ----------------------------------- -- - -- ------------------ --- --------------- - -------------------- - --- --- --- ---------------------展开代码
上面是一个简单的 WebSocket 服务器示例代码,它将广播客户端输入的数据。我们也可以像任何普通 Fastify 路由一样使用任意数量的 WebSocket 端点。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c93672e46428fe9e0513b5