μWebSockets.js 从入门到实战:安装、HTTP/WebSocket 核心 API 与性能特性全解析
发布时间:2026/9/25 17:46:42来源:尧图网络
后端Web框架WebSocket【免费下载链接】uWebSockets.jsμWebSockets for Node.js back-ends :metal:项目地址https://gitcode.com/gh_mirrors/uw/uWebSockets.js点击查看免费下载μWebSockets.jsµWS是一个以 C 为核心、通过原生 V8 插件暴露给 Node.js 的高性能标准合规 Web 服务器本文围绕仓库 README.md 的主线完整讲解其安装方式、第一个 HTTP 应用、路由系统、WebSocket 行为配置、异步处理、背压控制与发布订阅等核心主题。读完本文你将掌握 μWebSockets.js 的基本接入方式并能基于仓库中的真实示例与类型定义独立搭建可运行的 HTTP/WebSocket 服务。项目定位一个写在 C 里的 Node.js Web 服务器README 开门见山地给出了项目的三个关键词Simple简单、Secure安全、Standards compliant标准合规并补充说明其定位是为最苛刻的应用而设计的 Web 服务器。从技术实现上看μWebSockets.js 的服务器核心用约一万行 C 编写通过 V8 插件的形式接入 Node.js——这意味着 TCP 解析、TLS、HTTP、WebSocket 等协议层处理都在 C 侧完成JavaScript 侧只负责暴露 API。README 还指出自 2022 年起 μWS 的一个分支承担了 Bun 运行时的 event-loop、TLS、HTTP、QUIC、WebSockets、发布/订阅与 URL 路由等底层职责。如果你希望深入理解其底层 C 层实现可以阅读本仓库中 src/host.cpp、src/addon.cpp 以及 src/AppWrapper.h 等源码文件。值得一提的是README 中带有明确的性能声明项目宣称其性能优于 Node.js 生态中的 Fastify对应 v20.71.0 的 release 说明。这类性能数据属于项目自身的对外声明实际效果与具体负载、机器环境强相关生产选型时应以你自己的基准测试为准。安装通过 NPM 客户端从 GitHub 安装μWebSockets.js不在 NPM registry 中发布原因见后文许可证与分发安全一节而是通过 Git 仓库直接安装。README 给出的安装命令为npm install uNetworking/uWebSockets.js#v20.70.0即通过#tag指定版本标签。仓库 misc/npm.md 中还给出了另一种更注重供应链安全的安装方式——直接锁定提交的 SHA-1npm install uNetworking/uWebSockets.js#1977b5039938ad863d42fc4958d48c17e5a1fa06SHA-1 安装可以保证你拿到的二进制与指定源码提交一一对应仓库方为每个二进制发布都提供了对应的源码 SHA-1 引用与编译参数清单便于核对。运行环境限制从 src/uws.js 的模块加载逻辑可以看到仓库通过require(./uws_ process.platform _ process.arch _ process.versions.modules .node)按平台/架构/ABI 版本动态加载预编译原生模块。以 v20.70.0 为例加载失败时会抛出明确提示该版本仅支持 Node.js22、24、26且平台限定在glibcLinux、macOS 与 Windows 的 Tier 1 平台。因此安装前请确认你的 Node 版本在支持范围内。仓库根目录下的 Makefile 提供了从源码构建的能力运行时所需的模块名解析逻辑集中在 src/uws.js 中其中还包含一个DeclarativeResponse类src/uws.js用于把响应指令编码为二进制指令流供 C 侧高效执行。第一个应用Hello WorldREADME 将使用方式概括为Attach behavior to URL routes listen。最精简的 HTTP 服务来自 examples/HelloWorld.mjsimport uWS from ../dist/uws.js; const port 9001; const app uWS.App().get(/*, (res, req) { res.end(Hello World!); }).listen(port, (token) { if (token) { console.log(Listening to port port); } else { console.log(Failed to listen to port port); } });关键 API 解读uWS.App(options?)构造一个非 SSL 应用docs/index.d.ts。uWS.SSLApp(options)则构造 TLS 应用options即AppOptions包含key_file_name、cert_file_name、ca_file_name、passphrase、dh_params_file_name、ssl_ciphers以及ssl_prefer_low_memory_usage对应SSL_MODE_RELEASE_BUFFERS等字段见 docs/index.d.ts。示例中 SSL 版用到了misc/key.pem、misc/cert.pem与口令1234。.get(/*, handler)注册 HTTP GET 路由pattern 支持通配符/*TemplatedApp还提供post、options、del、patch、put、head、connect、trace与任意方法的anydocs/index.d.ts。.listen(port, cb)开始监听回调参数token为us_listen_socket时表示成功为false表示失败如端口被占用。同时支持listen(host, port, cb)、listen_unix(cb, path)以及带ListenOptions如LIBUS_LISTEN_EXCLUSIVE_PORT的重载docs/index.d.ts。路由系统静态、参数与通配符路由匹配规则在 examples/Router.mjs 中有完整演示const app uWS.App() .any(/anything, (res, req) { res.end(Any route with method: req.getMethod()); }) .get(/user/agent, (res, req) { res.end(Your user agent is: req.getHeader(user-agent)); }) .get(/static/yes, (res, req) { res.end(This is very static); }) .get(/candy/:kind, (res, req) { res.end(So you want candy? Have some req.getParameter(0) !); }) .get(/*, (res, req) { res.end(Nothing to see here!); });要点:kind形式的参数路由通过req.getParameter(0)按索引取值也支持按参数名取值req.getParameter(kind)docs/index.d.ts。/*通配符路由应放在最后作为兜底示例特意注释make sure to catch them last。HttpRequest对象是栈分配的只在当前回调执行期间有效不能保存到回调之外使用docs/index.d.ts。它提供getHeader(lowerCaseKey)返回小写键对应的值、getUrl()、getMethod()、getCaseSensitiveMethod()、getQuery()、getQuery(key)、forEach()遍历所有头以及setYield(bool)——把yield置为 true 表示当前处理器未处理该路由路由器会继续向后匹配docs/index.d.ts。WebSocket 服务行为配置与生命周期回调WebSocket 是 μWebSockets.js 的核心场景。examples/WebSockets.mjs 给出了完整的.ws(pattern, behavior)用法const app uWS.App().ws(/*, { /* Options */ compression: uWS.SHARED_COMPRESSOR, maxPayloadLength: 16 * 1024 * 1024, idleTimeout: 10, /* Handlers */ open: (ws) { console.log(A WebSocket connected!); }, message: (ws, message, isBinary) { let ok ws.send(message, isBinary); }, drain: (ws) { console.log(WebSocket backpressure: ws.getBufferedAmount()); }, close: (ws, code, message) { console.log(WebSocket closed); } }).any(/*, (res, req) { res.end(Nothing to see here!); }).listen(port, (token) { /* ... */ });WebSocketBehavior 配置项全览依据 docs/index.d.tsbehavior支持以下配置与回调含默认值配置/回调说明默认值maxPayloadLength单条消息最大字节数超限立即关闭连接16 * 1024closeOnBackpressureLimit消息因背压被丢弃时是否自动关闭连接falsemaxLifetime连接最大存活分钟数0 禁用合法值为 0 和 1–2390idleTimeout收发空闲超时秒数超时关闭0 禁用超时粒度通常约 4 秒并四舍五入120compressionpermessage-deflate 压缩策略见下文压缩选项uWS.DISABLEDmaxBackpressure单 socket 允许的最大背压字节数慢接收方超限将被跳过发布64 * 1024sendPingsAutomatically是否依据 idleTimeout 自动发送 ping 保持连接—upgrade拦截 HTTP 升级请求可异步执行—open新连接建立WebSocket 从 open 到 close 均有效—message收到消息消息以ArrayBuffer给出回调期间有效且返回后会被neutered置空如需保留必须复制—dropped消息因背压设置被丢弃时触发—drain背压排空后可继续发送的时机—close连接关闭无论错误、超时或正常关闭此后再不得使用该 WebSocket—ping/pong收到控制帧pong 会自动回复一般无需处理—subscription订阅/退订变化时触发回调携带 topic 与新旧订阅计数—WebSocket 实例 APIWebSocketUserDatadocs/index.d.ts核心方法send(message, isBinary?, compress?)发送消息返回1成功、2因背压上限被丢弃、0表示产生了背压会随后排空。发送前后可用getBufferedAmount()检查积压量。end(code?, shortMessage?)优雅关闭先送达已 send 的消息再发关闭帧并立即触发 close 回调。close()立即强制关闭对应close()系统调用不再发送关闭帧已排队消息不保证送达。ping()/subscribe(topic)/unsubscribe(topic)/isSubscribed(topic)/getTopics()/publish(topic, message, isBinary?, compress?)v20 起保证有序。cork(cb)在回调中合并多次发送为一次系统调用/TLS 块。getRemoteAddress()/getRemoteAddressAsText()/getRemotePort()/getUserData()。分片发送sendFirstFragment/sendFragment/sendLastFragment适用于超大消息分块传输。WebSocket.send的返回值语义与背压直接相关务必阅读下文背压一节。手动升级从 HTTP 到 WebSocket当需要基于自定义逻辑决定是否升级时使用upgrade回调。examples/Upgrade.mjs 展示了完整流程.ws(/*, { upgrade: (res, req, context) { console.log(An Http connection wants to become WebSocket, URL: req.getUrl() !); res.upgrade( { myData: req.getUrl() }, /* UserData见 WebSocket.getUserData() */ req.getHeader(sec-websocket-key), req.getHeader(sec-websocket-protocol), req.getHeader(sec-websocket-extensions), context); }, open: (ws) { console.log(A WebSocket connected with URL: ws.myData); }, /* ... */ })注意res.upgrade(...)调用后会立即触发 open 回调之后不得再使用res对象三个 WebSocket 头必须拼写正确否则升级会失败。对应的类型签名位于 docs/index.d.ts。context是us_socket_context_t即 uSockets 层的原生 socket 上下文docs/index.d.ts。异步处理器onAborted 与 cork 的正确姿势examples/AsyncFunction.mjs 演示了在异步处理器中安全响应的方法.get(/*, async (res) { res.onAborted(() { res.aborted true; }); let r await someAsyncTask(); /* await 会让出控制权返回 C必须先注册 onAborted */ if (!res.aborted) { /* 若已 abort 则不能响应 */ res.cork(() { res.end(r); }); } })两个关键点必须注册 abort 处理器凡是不能立即在回调内完成响应的 HTTP 请求都必须调用res.onAborted(handler)。返回处理器却不注册属于误用并会被终止abort 事件触发后响应对象即失效docs/index.d.ts。await 之后要用 cork在路由处理器顶部同步执行的部分默认处于 corked 状态但从await返回、或从异步数据库回调等场景中继续写响应时应显式cork(cb)把writeStatus、writeHeader、write合并为一次原子 IO。这对 TLS 尤其重要——否则每次写都会单独发一个 TLS 块、单独做一次 send 系统调用docs/index.d.ts。读取请求体onData 与 collectBodyexamples/JsonPost.mjs 演示了读取 POST JSON 的完整模式.post(/*, (res, req) { let url req.getUrl(); readJson(res, (obj) { console.log(Posted to url : , obj); res.end(Thanks for this json!); }, () { console.log(Invalid JSON or no data at all!); }); }) function readJson(res, cb, err) { let buffer; res.onData((ab, isLast) { let chunk Buffer.from(ab); if (isLast) { /* JSON.parse(Buffer.concat([buffer, chunk])) 或 JSON.parse(chunk) */ } else { buffer Buffer.concat([buffer, chunk]); } }); res.onAborted(err); }要点onData(handler)必须在任何异步操作之前注册否则数据可能丢失返回时 ArrayBuffer 会被置空因此isLast为 false 时必须复制数据docs/index.d.ts。更便捷的替代是res.collectBody(maxSize, handler)自动累积所有分片收齐后以完整ArrayBuffer回调若总大小超过maxSize则回调nulldocs/index.d.ts。onDataV2变体额外提供maxRemainingBodyLengthBigInt可据此预分配接收缓冲区docs/index.d.ts。解析失败时示例调用res.close()它会触发 onAborted 回调。背压慢接收方与全服务器稳定性examples/Backpressure.mjs 的注释把背压讲得非常透彻背压是未确认数据的堆积。数据不会凭空瞬间到达接收方而要靠 ACK 与传输窗口控制因此任何慢接收方若不加控制都可能拖垮整个服务器。示例用发送直到积压超过阈值、在 drain 回调里继续发送的方式演示了概念示例本身是教学演示不是生产写法open: (ws) { while (ws.getBufferedAmount() backpressure) { ws.send(This is a message, lets call it messageNumber); messageNumber; } }, drain: (ws) { while (ws.getBufferedAmount() backpressure) { ws.send(This is a message, lets call it messageNumber); messageNumber; } }生产实践建议发送前/后用ws.getBufferedAmount()评估积压配合drain回调背压排空后再继续推。通过maxBackpressure默认 64KB与closeOnBackpressureLimit限制单连接积压上限publish发布时超过背压上限的慢订阅者会被跳过直到其追赶上来或超时。WebSocket.send的返回值1 成功 / 2 丢弃 / 0 已积压就是为这套机制设计的信号。HTTP 响应细节流式输出、状态码与头HttpResponsedocs/index.d.ts提供以下能力writeStatus(200 OK)写状态行必须最先调用否则自动以 200 OK 补写。注意WebSocket 升级响应中若要自定义头需先写101 Switching Protocols再写头否则首次writeHeader会以 200 OK 写状态导致升级失败。writeHeader(key, value)写响应头。响应以线性缓冲而非哈希表格式输出这正与 cork 机制配合。write(chunk)进入/继续 chunked 编码返回是否未新增背压beginWrite()立即刷新头。end(body?, closeConnection?)结束响应endWithoutBody(reportedContentLength?, closeConnection?)无 body 结束。tryEnd(fullBodyOrChunk, totalSize)返回[ok, hasResponded]与onWritable(handler)配合实现流式大响应getWriteOffset()给出全局写入字节偏移供续写。onAborted、onData/onDataV2、collectBody见上文cork(cb)见异步处理器一节。getRemoteAddress()/getRemoteAddressAsText()/getRemotePort()以及 PROXY Protocol v2 相关的getProxiedRemoteAddress*/getProxiedRemotePort()。允许任意挂载用户数据[key: string]: any。一个遍历所有请求头的调试示例见 examples/Headers.mjsreq.forEach((k, v) ...)注意示例注释明确提示该方法仅供调试不要用于生产解决问题。发布/订阅与多路复用应用级app.publish(topic, message, isBinary?, compress?)与app.numSubscribers(topic)docs/index.d.ts配合WebSocket.subscribe/unsubscribe构成轻量 pub/subsubscription回调可感知订阅数变化docs/index.d.ts。完整示例见 examples/PubSub.mjs 与 examples/Broadcast.mjs。Worker 线程分发app.getDescriptor()、addChildAppDescriptor(descriptor)、removeChildAppDescriptor(descriptor)用于多线程场景docs/index.d.ts可配合 examples/WorkerThreads.mjs 阅读。SNI 多域名addServerName(hostname, options)、domain(domain)、removeServerName、missingServerNamedocs/index.d.ts示例见 examples/ServerName.mjs。连接计数filter(cb)可跟踪 socket 连接/断开app.close()强制关闭全部连接与监听 socket。压缩选项与环境变量CompressOptionsdocs/index.d.ts任意压缩器与解压器可通过按位或组合。uWS.DISABLED不压缩采用高效二进制协议时始终是好选择。uWS.SHARED_COMPRESSOR/uWS.SHARED_DECOMPRESSOR零内存开销的共享压缩/解压。uWS.DEDICATED_COMPRESSOR_3KB ... 256KB每 socket 独占滑动窗口内存开销即窗口大小3KB–256KB。uWS.DEDICATED_DECOMPRESSOR_512B ... 32KB与DEDICATED_DECOMPRESSOR每 socket 独占解压窗口各自在窗口大小之外另需约 23KB 固定开销。环境变量docs/index.d.tsUWS_HTTP_MAX_HEADERS_SIZEHTTP 请求头总字节上限运行时环境变量默认 4096。UWS_HTTP_MAX_HEADERS_COUNT请求头数量上限编译期宏定义非运行时变量默认 100。许可证与分发安全项目采用双轨许可知识产权保留但明确标注的源码以Apache License 2.0OSI 批准的宽松许可授权修改版 fork 必须仅基于许可源码且须以不同产品名发布README.md。分发策略方面README 与 misc/npm.md 解释了为何不进入 NPM registry通过 Git 的 SHA-1 保证二进制与源码一一对应、便于核对编译参数同时保留对发布与合规如 GDPR/DMCA的完全控制。文章开头给出的npm install uNetworking/uWebSockets.js#v20.70.0与 SHA-1 安装两种方式都适用于生产环境选择哪一种取决于你对供应链可追溯性的要求。继续深入仓库自带的资源地图API 权威定义docs/index.d.tsApp/SSLApp、TemplatedApp、WebSocket、HttpResponse、HttpRequest、WebSocketBehavior、AppOptions、CompressOptions、EnvironmentVariables等全部类型类型文档站点源文件位于 docs/generated。可直接运行的示例examples 目录包含 25 个场景示例HelloWorld、WebSockets、Upgrade/UpgradeAsync、Router、JsonPost、Backpressure、Broadcast、PubSub、ServerSentEvents、SlowReceiver、Upload、ProxyProtocol、RateLimit、GracefulShutdown、VideoStreamer等示例统一使用misc/key.pem与misc/cert.pem演示 SSL口令1234。原生模块加载与响应指令编码src/uws.jsC 包装层src/AppWrapper.h、src/HttpResponseWrapper.h、src/WebSocketWrapper.h、src/HttpRequestWrapper.h、src/addon.cpp。测试tests/smoke.js、tests/Hammer.js、tests/Autobahn.js含 tests/fuzzingclient.json 的 Autobahn 测试配置。构建根目录 Makefile 与 Qt 项目文件 misc/addon.pro。上手路径建议先用HelloWorld.mjs验证安装与环境再依次阅读WebSockets.mjs行为配置、Upgrade.mjs协议升级、Backpressure.mjs背压语义最后结合 docs/index.d.ts 按需查阅完整类型签名即可在项目中稳定落地。赞分享后端Web框架WebSocket【免费下载链接】uWebSockets.jsμWebSockets for Node.js back-ends :metal:项目地址https://gitcode.com/gh_mirrors/uw/uWebSockets.js点击查看免费下载相关推荐Julius工具链完全解析从语法构建到模型转换的开发者手册Julius工具链完全解析从语法构建到模型转换的开发者手册 Julius工具链 是构建专业级语音识别系统的关键所在️ 作为一款开源的大词汇量连续语音识别语音/音频人工智能深度学习Electric 1.0新特性HTTP API与Shapes核心功能详解Electric 1.0新特性HTTP API与Shapes核心功能详解 引言从数据库同步痛点到Electric 1.0解决方案 你是否还在为Postgre后端数据同步数据库人工智能AI AgentMCP 服务Garnet发布版本说明v1.0到v2.0新特性对比Garnet发布版本说明v1.0到v2.0新特性对比 引言从基础到飞跃的技术演进 Garnet作为微软研究院推出的新一代分布式缓存存储系统Cache St缓存KV存储后端上一篇Cilium 策略选择器缓存排查指南cilium-dbg policy selectors 命令详解下一篇Data Formulator 统一错误处理协议实战指南从 AppError 到 NDJSON 流事件的前后端一致设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网