socket.io-client 版本演进全解:从 CHANGELOG 读懂 4.x 客户端的全部重要发布与核心特性
本文以 packages/socket.io-client/CHANGELOG.md 为主体,完整梳理 socket.io-client 从 2.1.0 到 4.8.3 的全部版本发布记录、破坏性变更与特性演进,并结合 lib/socket.ts、lib/index.ts、package.json 等源码佐证每个特性在客户端中的真实落地方式,帮助读者在升级、选型和排障时快速理解"哪个版本引入了什么、底层是怎么实现的"。
一、版本总览:发布记录与 Bundle 体积
CHANGELOG 开头是一张版本总表,列出每个版本的发布日期和 UMD 构建(min+gzip)后的 Bundle 体积。完整表格如下:
| Version | Release date | Bundle size (UMD min+gzip) |
|---|---|---|
| 4.8.3 | December 2025 | 14.4 KB |
| 4.8.2 | December 2025 | 14.4 KB |
| 4.8.1 | October 2024 | 14.4 KB |
| 4.8.0 | September 2024 | 14.4 KB |
| 4.7.5 | March 2024 | 14.6 KB |
| 4.7.4 | January 2024 | 14.5 KB |
| 4.7.3 | January 2024 | 14.5 KB |
| 4.7.2 | August 2023 | 14.5 KB |
| 4.7.1 | June 2023 | 14.1 KB |
| 4.7.0 | June 2023 | 14.0 KB |
| 4.6.2 | May 2023 | 13.4 KB |
| 4.6.1 | February 2023 | 13.3 KB |
| 4.6.0 | February 2023 | 13.3 KB |
| 4.5.4 | November 2022 | 12.8 KB |
| 4.5.3 | October 2022 | 12.8 KB |
| 4.5.2 | September 2022 | 12.7 KB |
| 2.5.0(来自 2.x 分支) | June 2022 | 18.8 KB |
| 4.5.1 | May 2022 | 12.7 KB |
| 4.5.0 | April 2022 | 12.7 KB |
| 4.4.1 | January 2022 | 12.3 KB |
| 4.4.0 | November 2021 | 12.3 KB |
| 4.3.2 | October 2021 | 12.1 KB |
| 4.3.1 | October 2021 | 12.1 KB |
| 4.3.0 | October 2021 | 12.1 KB |
| 4.2.0 | August 2021 | 15.2 KB |
| 4.1.3 | July 2021 | 14.9 KB |
| 4.1.2 | May 2021 | 14.9 KB |
| 4.1.1 | May 2021 | 14.9 KB |
| 4.1.0 | May 2021 | 14.9 KB |
| 4.0.2 | May 2021 | 14.9 KB |
| 4.0.1 | March 2021 | 14.9 KB |
| 3.1.3(来自 3.1.x 分支) | March 2021 | 14.6 KB |
| 4.0.0 | March 2021 | 14.9 KB |
| 3.1.2 | February 2021 | 14.6 KB |
| 3.1.1 | February 2021 | 14.5 KB |
| 3.1.0 | January 2021 | 14.5 KB |
| 3.0.5 | January 2021 | 14.5 KB |
| 2.4.0(来自 2.x 分支) | January 2021 | 18.8 KB |
| 3.0.4 | December 2020 | 14.6 KB |
| 3.0.3 | November 2020 | 14.5 KB |
| 3.0.2 | November 2020 | 14.5 KB |
| 3.0.1 | November 2020 | 14.7 KB |
| 3.0.0 | November 2020 | 14.6 KB |
| 2.3.1 | September 2020 | 18.8 KB |
| 2.3.0 | September 2019 | 19.6 KB |
| 2.2.0 | November 2018 | 18.6 KB |
| 2.1.1 | May 2018 | 18.7 KB |
| 2.1.0 | March 2018 | 18.7 KB |
从这张表可以读出几条演进线索:
- 3.0.0(2020-11)是协议 v4 对应的客户端大版本,与 2.x 系列并行维护;2.x 分支后来又单独发布了 2.4.0、2.5.0 供仍停留在旧协议的用户使用。
- 4.0.0(2021-03) 因为服务端有破坏性变更而强制升主版本号,此后一直沿 4.x 迭代至今(当前 package.json 中
"version": "4.8.3")。 - Bundle 体积从 2.x 的约 18.7 KB 降到 4.5.x 的约 12.7 KB,4.2.0 曾短暂升到 15.2 KB(引入了定时器实现变化),4.6.0 起稳定在 13.3 KB,最新 4.8.3 为 14.4 KB。
每个版本的"Dependencies"小节都记录了 engine.io-client 与 ws 的版本联动,例如 4.8.3 携带 engine.io-client@~6.6.1 和 ws@~8.18.3。值得注意的是,服务端发布小版本 bug fix 时,客户端常常需要"被动跟进"一次版本号——4.8.3、4.7.4、4.5.1、4.1.1 的发布说明都是"There were some minor bug fixes on the server side, which mandate a client bump",这类版本本身没有客户端新特性,阅读时可以直接跳过。
二、4.8.x 系列:依赖更新与发送队列修复
4.8.3(2025-12-23)
服务端有若干小 bug 修复,要求客户端跟进升版。依赖变化:engine.io-client@~6.6.1(无变化)、ws 从 ~8.17.1 升到 ~8.18.3。
4.8.2(2025-12-22)
两个 bug 修复:
- bundle: do not mangle the "_placeholder" attribute (bis):4.8.1 中"打包时不要混淆
_placeholder属性"的修复不彻底,此处再次修复。_placeholder是socket.io-parser序列化二进制数据时用于在 JSON 中占位的内部属性,被打包工具重命名会导致二进制数据还原失败,因此必须原样保留。 - drain queue before emitting "connect":连接建立后,先把发送缓冲区(sendBuffer)中排队的事件发送出去,再触发
"connect"事件。这避免了用户代码在connect回调里emit时,事件顺序排在旧缓冲事件之后的问题。
4.8.1(2024-10-25)
修复 bundle: do not mangle the "_placeholder" attribute,即上面提到的打包混淆问题首次修复,依赖版本未变化。
这三个版本的 lib/socket.ts 中,emit() 方法在构造二进制包时依赖 socket.io-parser 生成的 _placeholder 字段,与 4.8.1/4.8.2 的修复内容相互印证。
三、4.8.0:自定义传输实现与 tryAllTransports
这是 4.8 系列中唯一的功能性大版本,带来两个重要特性。
特性 1:transports 选项接受传输实现类数组
之前 transports 只接受字符串数组(如 ["polling", "websocket"]),4.8.0 起可以直接传入 engine.io-client 导出的传输实现类:
import { io } from "socket.io-client";
import { XHR, WebSocket } from "engine.io-client";
const socket = io({
transports: [XHR, WebSocket]
});
仓库中官方提供的实现类有 6 种(在 lib/index.ts 中直接从 engine.io-client 再导出,用户甚至可以从 socket.io-client 顶层直接 import):
| Transport | 说明 |
|---|---|
Fetch |
基于内置 fetch() 的 HTTP 长轮询 |
NodeXHR |
基于 xmlhttprequest-ssl 包提供 XMLHttpRequest 的 HTTP 长轮询 |
XHR |
基于内置 XMLHttpRequest 对象的 HTTP 长轮询 |
NodeWebSocket |
基于 ws 包的 WebSocket 传输 |
WebSocket |
基于内置 WebSocket 对象的 WebSocket 传输 |
WebTransport |
基于内置 WebTransport 对象的 WebTransport 传输 |
各运行时下的可用性矩阵(来自 CHANGELOG 原文):
| Transport | browser | Node.js | Deno | Bun |
|---|---|---|---|---|
Fetch |
✔ | ✔ (1) | ✔ | ✔ |
NodeXHR |
✔ | ✔ | ✔ | |
XHR |
✔ | |||
NodeWebSocket |
✔ | ✔ | ✔ | |
WebSocket |
✔ | ✔ (2) | ✔ | ✔ |
WebTransport |
✔ | ✔ |
(1) Node.js 自 v18.0.0 起提供全局 fetch;(2) Node.js 自 v21.0.0 起提供全局 WebSocket。
从源码结构看,engine.io-client 中各传输类定义于 transports/polling-fetch.ts、transports/polling-xhr.ts、transports/polling-xhr.node.ts 等文件,socket.io-client 只是做了透传导出,因此选择具体实现类即可精确控制长轮询走 fetch 还是 XHR、Node 下 WebSocket 走内置还是 ws 包。
特性 2:tryAllTransports 选项
当首个传输(通常是 HTTP 长轮询)失败时,如果设置了 tryAllTransports: true,则其余传输也会被逐一测试:
import { io } from "socket.io-client";
const socket = io({
tryAllTransports: true
});
适用场景:
- 服务端禁用了 HTTP 长轮询,或 CORS 校验失败;
- WebSocket 被优先测试时(
transports: ["websocket", "polling"])。
CHANGELOG 明确提示了唯一潜在缺点:失败时连接尝试可能更耗时——有用户报告 WebSocket 连接错误需要数秒才能被检测到(这正是默认先用 HTTP 长轮询的原因),所以该选项默认为 false。
engine.io-client 的测试 中有对应的验证用例:"should connect with the 2nd transport if tryAllTransports is 'true' (polling)"、"...(websocket)" 以及 "should not connect with the 2nd transport if tryAllTransports is 'false'",分别覆盖了 polling 与 websocket 两种第二传输的切换和默认关闭行为。
4.8.0 的 bug 修复
- accept string | undefined as init argument (bis):类型定义层面接受
string | undefined初始化参数; - allow to manually stop the reconnection loop:允许手动停止重连循环;
- close the engine upon decoding exception:解码异常时关闭底层 Engine;
- do not send a packet on an expired connection (#5134):连接已过期(ping 超时)时不再发送数据包。
对应依赖升级为 engine.io-client@~6.6.1、ws@~8.17.1。
四、4.7.x 系列:WebTransport 打磨与 Node.js Cookie 支持
4.7.0(2023-06-22)
4.7.0 是 4.x 后期最重要的功能版本,包含三个特性:
1. 支持 WebTransport 传输
Engine.IO 客户端自此可以把 WebTransport 作为底层传输。WebTransport 是基于 HTTP/3 协议的双向传输 Web API,适用于 Web 客户端与 HTTP/3 服务器之间的双向通信。
Node.js 客户端:在 Node.js 原生支持 WebTransport 之前,可以使用 @fails-components/webtransport 包填充全局对象:
import { WebTransport } from "@fails-components/webtransport";
global.WebTransport = WebTransport;
本仓库中的 examples/webtransport/ 示例提供了完整的 WebTransport 服务端与客户端演示(含证书生成脚本 generate_cert.sh)。
2. Node.js 客户端的 Cookie 管理
设置 withCredentials: true 后,Node.js 客户端会在 HTTP 请求中携带 Cookie,方便配合基于 Cookie 的 sticky session(集群部署时把同一客户端的路由固定到某个节点):
import { io } from "socket.io-client";
const socket = io("https://example.com", {
withCredentials: true
});
3. ESM 构建的条件导入(含 debug 日志)
默认情况下,浏览器环境的 ESM 构建不包含 debug 包,因为它会增加 Bundle 体积——副作用是即使设置了 localStorage.debug,devtools 控制台也看不到调试日志。4.7.0 起可以通过 条件导出 的思路导入含 debug 的构建。以 Vite 为例:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 4000
},
resolve: {
conditions: ["development"]
}
})
从当前 package.json 的 exports 字段可以印证这一机制:import 条件在 Node 环境下会解析到 ./build/esm-debug/index.js(带 debug 的构建),浏览器默认解析到 ./build/esm/index.js(不带 debug 的构建),另有一个 ./debug 子路径显式指向带 debug 的构建。
4.7.0 还包含两个 bug 修复:
- properly report timeout error when connecting:连接超时时正确上报 timeout 错误;
- use same scope for setTimeout and clearTimeout calls (#1568):
setTimeout与clearTimeout使用同一作用域,修复跨环境定时清理问题。
4.7.1(2023-06-28)
引入 engine.io-client 的两个修复:
closeOnBeforeunload默认值改为false;- WebTransport 下正确处理被突然关闭的连接。
4.7.2(2023-08-02)
引入 engine.io-client 的两个 WebTransport 修复:
- webtransport: add proper framing(正确的帧格式);
- webtransport: honor the binaryType attribute(遵守
binaryType属性)。
4.7.3(2024-01-03)
- 改进与 Node 16 模块解析的兼容性 (#1595):修复
exports条件在旧版 Node 上的解析问题; - typings: 接受
string | undefined作为 init 参数; - typings: 修正
socket#id属性的类型。
4.7.4 / 4.7.5(2024-01 / 2024-03)
- 4.7.4:服务端小修复引发的跟进升版,客户端无变化。
- 4.7.5:修复 discard acknowledgements upon disconnection——断开连接时丢弃挂起的 ack 回调,避免断线后 ack 定时器/回调残留造成内存泄漏或误回调。
五、4.6.x 系列:可靠性特性的集中落地
4.6.0(2023-02-07)
4.6.0 一次性引入了四个重要特性,是理解当前 Socket 实现的关键版本。
特性 1:addTrailingSlash 选项
此前 Engine.IO 客户端默认会在请求路径后追加尾部斜杠。该选项可以关闭这一行为:
import { io } from "socket.io-client";
const socket = io("https://example.com", {
addTrailingSlash: false
});
示例中请求 URL 为 https://example.com/socket.io 而不是 https://example.com/socket.io/。在 engine.io-client 的 socket 实现 中,addTrailingSlash 默认值为 true,URL 拼接处形如 (this.opts.addTrailingSlash ? "/" : ""),与 CHANGELOG 描述一致。
特性 2:Promise 风格的确认(emitWithAck)
在 ack 回调之上增加的语法糖:
// without timeout
const response = await socket.emitWithAck("hello", "world");
// with a specific timeout
try {
const response = await socket.timeout(1000).emitWithAck("hello", "world");
} catch (err) {
// the server did not acknowledge the event in the given delay
}
注意:不支持 Promise 的环境需要自行添加 polyfill 才能使用。
lib/socket.ts 中的实现印证了这一点:emitWithAck() 内部就是 new Promise((resolve, reject) => ...),把 ack 回调包装为"第一参数为错误则 reject,否则 resolve 第二参数"的形式,并标记 fn.withError = true 以便框架识别该回调需要接收超时错误。
特性 3:连接状态恢复(Connection State Recovery)
允许客户端在短暂断线后重连,恢复会话 ID 并补收断线期间错过的包(需要在服务端启用该功能)。socket 对象上新增布尔属性 recovered:
socket.on("connect", () => {
console.log(socket.recovered); // whether the recovery was successful
});
源码层面,lib/socket.ts 中:
- 断线重连时,
onconnect处理函数里执行this.recovered = pid && this._pid === pid——即服务端回传的pid存在且与本地保存的上次会话 ID 一致,才判定为"恢复成功"; - 重新连接握手时会把
Object.assign({ pid: this._pid, offset: this._lastOffset }, data)附加到 auth 数据中,把上次断点的offset告知服务端,服务端据此补发错过的包。
仓库提供了完整的示例工程 examples/connection-state-recovery-example/,含 CJS/ESM 两种用法及演示动图。
特性 4:重发机制(retries 与 ackTimeout)
两个新选项:
retries:最大重试次数,超过上限后该包被丢弃;ackTimeout:等待确认的默认超时(毫秒)。注意不要与已存在的timeout选项混淆——timeout是 Manager 在连接阶段使用的。
const socket = io({
retries: 3,
ackTimeout: 10000
});
// implicit ack
socket.emit("my-event");
// explicit ack
socket.emit("my-event", (err, val) => { /* ... */ });
// custom timeout (in that case the ackTimeout is optional)
socket.timeout(5000).emit("my-event", (err, val) => { /* ... */ });
以上所有示例中,"my-event" 会被发送最多 4 次(1 + 3),直到服务端返回确认。CHANGELOG 强调:为每个包分配唯一 ID 是用户的责任,这样才能在服务端做去重。
当前 lib/socket.ts 中 SocketOptions 的注释把这一点写得更清楚:使用 Infinity 意味着投递保证为 "at-least-once"(默认为 "at-most-once"),但实践中 10 左右的重试次数通常足够。实现上的关键路径:
emit()检测到this._opts.retries且包不是volatile、不在队列中时,转入_addToQueue();_addToQueue()为每个包记录tryCount,ack 回调里若packet.tryCount > this._opts.retries则打印packet [%d] is discarded after %d tries并出队;_registerAckCallback()中,const timeout = this.flags.timeout ?? this._opts.ackTimeout——单次socket.timeout(n)的临时值优先于全局ackTimeout,超时时回调以new Error("operation has timed out")触发,这正是 4.6.0 同时修复的 "properly type emits with timeout" (#1570) 所处理的类型场景。
4.6.1(2023-02-20)
- do not drain the queue while the socket is offline:socket 离线时不发送队列,防止重试逻辑对未连接 socket 无效发包;
- prevent duplicate connections when multiplexing:修复多路复用(multiplexing)时可能建立重复连接的问题。
4.6.2(2023-05-31)
exports: move types condition to the top (#1580):把 types 条件移到 exports 映射的最前面,修复部分 Node/工具链按顺序匹配 exports 条件时找不到类型定义的问题。当前 package.json 的 exports 字段中,import 与 require 下的 types 条件均位于首位,即为此次修复后的形态。
六、4.5.x 系列:排障增强与协议安全
4.5.0(2022-04-23)
三个特性显著提升了排障能力:
1. disconnect 事件携带详细信息
"disconnect" 事件现在包含第二个 details 参数,帮助定位断线原因。例如 HTTP 长轮询模式下 payload 超过 maxHttpBufferSize 时:
socket.on("disconnect", (reason, details) => {
console.log(reason); // "transport error"
// in that case, details is an error object
console.log(details.message); "xhr post error"
console.log(details.description); // 413 (the HTTP status of the response)
// details.context refers to the XMLHttpRequest object
console.log(details.context.status); // 413
console.log(details.context.responseText); // ""
});
类型定义上,lib/socket.ts 中的 DisconnectDescription 联合类型(Error | { description: string; context?: unknown })与 disconnect: (reason, description?) 的保留事件签名,正是这一特性的落地。
2. 出站包的全量监听器 onAnyOutgoing
类似 onAny(),但针对出站包:
socket.onAnyOutgoing((event, ...args) => {
console.log(event);
});
适合做客户端侧埋点、调试或日志审计。
3. 按 maxPayload 切分写缓冲
服务端现在会在握手详情中携带 maxPayload 字段,客户端据此决定一次发送多少个包,使其总量低于服务端的 maxHttpBufferSize,从而避免上面的 413 错误。该字段由 engine.io-client 实现,examples/basic-websocket-client/ 等示例的长轮询升级路径即受此逻辑影响。
4.5.1 / 4.5.2 / 4.5.3(2022-05 ~ 2022-10)
- 4.5.1:服务端小修复引发的跟进升版;
- 4.5.2:handle ill-formatted packet from server——容忍服务端返回的格式错误包,避免客户端崩溃;
- 4.5.3:do not swallow user exceptions——不再吞掉用户代码抛出的异常,保证错误能正常冒泡到调用方。
4.5.4(2022-11-22):CVE-2022-2421 修复
该版本升级了 socket.io-parser 依赖,用于修复 CVE-2022-2421 漏洞。仍在使用 4.5.x 旧版本且依赖 socket.io-parser 解析不可信数据的项目,应关注此安全更新。
2.5.0(2022-06-26,2.x 分支)
2.x 系列的收尾版本,仅包含一项修复:ensure buffered events are sent in order(保证缓冲事件按序发送),依赖保持 engine.io-client@~3.5.0 与 ws@~7.4.2。
七、4.4.x ~ 4.1.0:超时特性与构建体系
4.4.0(2021-11-18)
最重要的新特性是 timeout() 方法:
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// the server did not acknowledge the event in the given delay
}
});
即对单次 emit 设置 ack 超时,超时后 ack 回调收到一个 Error。它与 4.6.0 的 ackTimeout(全局默认值)配套,flags.timeout 优先——这一优先级在 _registerAckCallback() 的 this.flags.timeout ?? this._opts.ackTimeout 实现中可以直接看到。
同版本 bug 修复:
- 嵌套
package.json中补上包名(修复工具链读到的 name 错误,#1513); - 修复
socket.disconnect().connect()的用法; - 防止 middleware 失败后 socket 继续重连(middleware 返回的
connect_error不应触发重连风暴)。
4.3.x(2021-10)
- 4.3.0:提供 ESM bundle,可以直接以 ES Module 引入官方构建(CHANGELOG 原例使用 CDN,仓库内对应产物为 packages/socket.io/client-dist/socket.io.esm.min.js):
<script type="module">
import { io } from "./socket.io.esm.min.js";
const socket = io();
socket.emit("hello", "world");
</script>
同时迁移到 rollup 构建(migrate to rollup),并补齐部分 emitter 方法的类型定义(#1502)。
- 4.3.1 / 4.3.2:连续两次"恢复默认导出 / 恢复 namespace 导出"的紧急修复,说明 4.3.0 的模块导出结构改动影响了既有
import io from "socket.io-client"用法,4.3.2 完成 (bis) 兜底。
4.2.0(2021-08-30)
- 新特性:add an option to use native timer functions (#1479)——允许使用宿主环境的原生定时器,便于在 Web Worker、移动端等环境中接管计时;
- bug 修复:允许
randomizationFactor设为 0 (#1447),即完全禁用重连延迟随机化;类型层面允许 typed events 中的 async 监听器。
4.1.x(2021-05 ~ 2021-07)
- 4.1.0:新增
closeOnBeforeunload选项(来自engine.io-client),控制页面beforeunload时是否主动关闭传输,用于在"刷新页面"与"误触关闭"之间做取舍; - 4.1.1:服务端小修复引发的跟进升版;
- 4.1.2:类型定义补上缺失的
closeOnBeforeunload(#1469) 与requestTimeout(#1467) 选项; - 4.1.3:跟进修复版本。
4.0.x(2021-03 ~ 2021-05)
- 4.0.2:类型定义回退到无类型事件监听的兜底签名;保证缓冲事件按序发送;保证连接正确多路复用;正确导出
Socket类; - 4.0.1:类型定义把
auth属性改为 public (#1455);类型定义对齐wrapper.mjs的包装导出(#1456)。
八、4.0.0 与 3.x 系列:主版本升级的破坏性变更
4.0.0(2021-03-10)
CHANGELOG 原话:"The major bump is due to some breaking changes on the server side." 即客户端升主版本是为跟随服务端破坏性变更。新增特性:
- add autoUnref option:Node.js 场景下允许对内部定时器
unref(),避免定时器阻止进程退出; - add support for typed events:引入类型化事件(
TypedEvents),emit/on获得编译期事件名与参数校验,类型定义见 typed-events.ts 及测试 typed-events.test-d.ts; - bundle: restore support for JS modules:修复打包对 JS 模块的兼容。
3.0.0(2020-11-05):面向协议 v4 的大重构
3.0.0 相对 2.x 的主要变化(其中多数在 3.0.0-rc 系列中逐步引入,CHANGELOG 按 rc1~rc4 分条记录):
破坏性变更(BREAKING CHANGES):
"error"不再是保留事件,Socket 改为触发"connect_error":
// before
socket.on("error", () => {});
// after
socket.on("connect_error", () => {});
Socket#binary()方法被移除——该用法已由"允许提供自定义 parser"能力覆盖(参见 examples/custom-parsers/ 示例);- Socket 不再转发其 Manager 的事件。这些事件仍需从 Manager 实例访问:
socket.io.on("reconnect", () => {
// ...
});
其他重构与新特性:
- 中间件(auth/middleware)出错时发出
Error对象,而不是仅触发事件; - 增加包含 msgpack parser 的 bundle(对应产物 socket.io.msgpack.min.js,与 socket.io-parser 的 msgpack 支持配套);
- 增加 catch-all 监听器(
onAny()); - 增加 volatile 事件(
volatile标记:传输不可写时直接丢弃包); - 二进制检测移回 parser 层;
- 增加 ES6 module 导出;
- 不再复用 Engine.IO 的 id(Socket 会话 ID 由 Socket.IO 层独立管理);
- 移除对默认 namespace 的隐式连接;
- 拆分 Manager 与 Socket 的事件体系;
- 使用保留事件名时直接抛错。
3.1.x ~ 3.0.1(2020-11 ~ 2021-03)
- 3.1.3:bundle 恢复对 JS 模块的支持;
- 3.1.2:恢复 web workers 支持;
beforeunload钩子中静默关闭传输; - 3.1.1:manager ID 中包含 path(不同 path 的连接不再误复用同一 Manager);bundle 中移除
processpolyfill;类型定义补齐返回类型与通用重载签名 (#1440)、修正query选项类型 (#1439); - 3.1.0:
Manager#opts公开;允许整数作为事件名; - 3.0.5:连接失败时正确发出
connect_error事件(修复 3.0.x 早期"失败只静默"的问题);类型定义公开sendBuffer与receiveBuffer; - 3.0.4:客户端连到 v2.x 服务端时主动报
error(协议不兼容的快速失败),并跟踪活跃 socket;类型定义导出extraHeaders; - 3.0.3:ES modules wrapper 中正确导出
io; - 3.0.2 / 3.0.1:类型定义陆续导出
withCredentials、ManagerOptions、Socket、SocketOptions,并增加io命名导出。
这条线反映了一个现实:3.0 系列的类型定义导出是"挤牙膏"式的逐版补齐,使用 TypeScript 的用户在 3.0.x 早期版本可能频繁遇到"类型未导出"的报错。
九、2.x 末期版本
- 2.4.0(2021-01-04):版本号与服务端 2.x 对齐,本身无新特性;
- 2.3.1(2020-09-30):把
debug依赖回退到~3.1.0,因为新版 debug 含 ES6 语法,在 IE 浏览器中报错。CHANGELOG 特别注明:这只影响自己用 webpack 等工具打包 socket.io-client 的用户,官方dist/构建早已用 babel 转译;并提及可以查看社区的webpack-remove-debug插件作为替代方案。另有修复:修复异步打开 socket 后的重连问题 (#1253); - 2.3.0(2019-09-20):与服务端版本对齐,无新特性;
- 2.2.0(2018-11-29):移除对
global变量的所有引用(修复 #1166,解决某些浏览器环境global未定义的报错); - 2.1.1(2018-05-17):非根 namespace 下 middleware 失败时也触发 error 事件 (#1202);
- 2.1.0(2018-03-29):新增
binary标志,跳过默认的递归二进制扫描以提升性能:
// by default, the object is recursively scanned to check whether it contains some binary data
// in the following example, the check is skipped in order to improve performance
socket.binary(false).emit('plain-object', object);
(binary() 在 3.0.0 中移除,由自定义 parser 取代。)
十、基于源码的升级与选型建议
综合 CHANGELOG 全记录与当前仓库实现,给出几条可直接落地的结论:
- 客户端与服务端主版本必须匹配:3.0.4 引入的"连到 v2.x 服务端直接报错"说明协议版本不兼容是硬约束;4.x 客户端对应协议 v5(见 docs/socket.io-protocol/v5-current.md)。跨主版本混用不可行,2.x 用户只能停留在 2.x 分支的最后版本 2.5.0。
- 可靠性特性看 4.6.0 及以上:
retries/ackTimeout(at-least-once 投递)、emitWithAck、连接状态恢复、addTrailingSlash均在 4.6.0 落地,且此后版本(4.6.1 的离线不排空队列、4.7.5 的断线丢弃 ack、4.8.2 的 drain queue before emitting "connect")持续修补其边界行为。需要"消息不丢"语义的项目,建议以 4.6.x 为最低基线、以 4.8.3 为目标版本。 - 传输层控制看 4.8.0:自定义传输类数组与
tryAllTransports是 4.8.0 才有的能力;WebTransport 支持则从 4.7.0 开始(配套修复贯穿 4.7.1 ~ 4.7.2)。 - Node.js 与浏览器的构建差异由 exports 字段管理:当前 package.json 中,
import在 Node 下解析到带 debug 的build/esm-debug/index.js,浏览器解析到build/esm/index.js;require统一走 CJS。engines要求 Node>=10.0.0。直接引用dist/官方 bundle(UMD/ESM/msgpack 三种)则不走条件导出。 - 多路复用行为:lib/index.ts 中
lookup()按protocol://host:port/path生成 manager id 并在cache中复用连接(io('http://localhost/a')与io('http://localhost/b')共享底层连接),forceNew/multiplex: false可强制新建——4.0.2 与 4.6.1 的两次修复("ensure connections are properly multiplexed"、"prevent duplicate connections when multiplexing")正是针对这一机制的边界问题。
阅读本 CHANGELOG 时,可以按"Features / Bug Fixes / Dependencies"三段式快速扫描:Dependencies 段只关心 engine.io-client 大版本跳变(6.2 → 6.4 → 6.5 → 6.6 对应 WebTransport、重发机制等底层能力);服务端跟进式的 bump(4.8.3、4.7.4、4.5.1、4.1.1)可直接略过。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00