Skip to content

Commit b429db1

Browse files
authored
fix(node): websocket under node doesn't emit close+error (only error) so redials didn't happen (#219)
Introduce a `cleanup` method for socket event handling, ensuring consistent resource cleanup across close/error scenarios. Additionally, implement a test case to verify websocket reconnect functionality after disconnection. Signed-off-by: Alberto Ricart <[email protected]>
1 parent 2ce304c commit b429db1

22 files changed

+103
-51
lines changed

core/deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/nats-core",
3-
"version": "3.0.0-51",
3+
"version": "3.0.0-54",
44
"exports": {
55
".": "./src/mod.ts",
66
"./internal": "./src/internal_mod.ts"

core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/nats-core",
3-
"version": "3.0.0-51",
3+
"version": "3.0.0-54",
44
"files": [
55
"lib/",
66
"LICENSE",

core/src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// This file is generated - do not edit
2-
export const version = "3.0.0-51";
2+
export const version = "3.0.0-54";

core/src/ws_transport.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,12 @@ export class WsTransport implements Transport {
136136

137137
// @ts-ignore: CloseEvent is provided in browsers
138138
this.socket.onclose = (evt: CloseEvent) => {
139-
this.socketClosed = true;
140139
let reason: Error | undefined;
141140
if (!evt.wasClean && evt.reason !== "") {
142141
reason = new Error(evt.reason);
143142
}
144143
this._closed(reason);
145-
this.socket.onopen = null;
146-
this.socket.onmessage = null;
147-
this.socket.onerror = null;
148-
this.socket.onclose = null;
149-
this.closedNotification.resolve(this.closeError);
144+
this._cleanup();
150145
};
151146

152147
// @ts-ignore: signature can be any
@@ -161,10 +156,24 @@ export class WsTransport implements Transport {
161156
} else {
162157
this._closed(err);
163158
}
159+
this._cleanup();
164160
};
165161
return ok;
166162
}
167163

164+
_cleanup() {
165+
if (this.socketClosed === false) {
166+
// node seems to not emit closed if there's an error
167+
// all other runtimes do.
168+
this.socketClosed = true;
169+
this.socket.onopen = null;
170+
this.socket.onmessage = null;
171+
this.socket.onerror = null;
172+
this.socket.onclose = null;
173+
this.closedNotification.resolve(this.closeError);
174+
}
175+
}
176+
168177
disconnect(): void {
169178
this._closed(undefined, true);
170179
}

jetstream/deno.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/jetstream",
3-
"version": "3.0.0-38",
3+
"version": "3.0.0-40",
44
"exports": {
55
".": "./src/mod.ts",
66
"./internal": "./src/internal_mod.ts"
@@ -33,6 +33,6 @@
3333
"test": "deno test -A --parallel --reload --trace-leaks --quiet tests/ --import-map=import_map.json"
3434
},
3535
"imports": {
36-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51"
36+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54"
3737
}
3838
}

jetstream/import_map.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"imports": {
33
"@nats-io/nkeys": "jsr:@nats-io/nkeys@~2.0.2",
44
"@nats-io/nuid": "jsr:@nats-io/nuid@~2.0.3",
5-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
6-
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-51/internal",
5+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
6+
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-54/internal",
77
"test_helpers": "../test_helpers/mod.ts",
88
"@std/io": "jsr:@std/[email protected]"
99
}

jetstream/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/jetstream",
3-
"version": "3.0.0-38",
3+
"version": "3.0.0-40",
44
"files": [
55
"lib/",
66
"LICENSE",
@@ -33,7 +33,7 @@
3333
},
3434
"description": "jetstream library - this library implements all the base functionality for NATS JetStream for javascript clients",
3535
"dependencies": {
36-
"@nats-io/nats-core": "3.0.0-51"
36+
"@nats-io/nats-core": "3.0.0-54"
3737
},
3838
"devDependencies": {
3939
"@types/node": "^22.10.10",

kv/deno.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/kv",
3-
"version": "3.0.0-32",
3+
"version": "3.0.0-34",
44
"exports": {
55
".": "./src/mod.ts",
66
"./internal": "./src/internal_mod.ts"
@@ -33,7 +33,7 @@
3333
"test": "deno test -A --parallel --reload --quiet tests/ --import-map=import_map.json"
3434
},
3535
"imports": {
36-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
37-
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-38"
36+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
37+
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-40"
3838
}
3939
}

kv/import_map.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"imports": {
3-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
4-
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-51/internal",
5-
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-38",
6-
"@nats-io/jetstream/internal": "jsr:@nats-io/jetstream@~3.0.0-38/internal",
3+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
4+
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-54/internal",
5+
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-40",
6+
"@nats-io/jetstream/internal": "jsr:@nats-io/jetstream@~3.0.0-40/internal",
77
"test_helpers": "../test_helpers/mod.ts",
88
"@nats-io/nkeys": "jsr:@nats-io/nkeys@~2.0.2",
99
"@nats-io/nuid": "jsr:@nats-io/nuid@~2.0.3",

kv/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/kv",
3-
"version": "3.0.0-32",
3+
"version": "3.0.0-34",
44
"files": [
55
"lib/",
66
"LICENSE",
@@ -33,8 +33,8 @@
3333
},
3434
"description": "kv library - this library implements all the base functionality for NATS KV javascript clients",
3535
"dependencies": {
36-
"@nats-io/jetstream": "3.0.0-38",
37-
"@nats-io/nats-core": "3.0.0-51"
36+
"@nats-io/jetstream": "3.0.0-40",
37+
"@nats-io/nats-core": "3.0.0-54"
3838
},
3939
"devDependencies": {
4040
"@types/node": "^22.10.10",

migration.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ The transports have also been migrated:
3939
support.
4040

4141
Note that when installing `@nats-io/transport-node` or
42-
`@nats-io/transport-deno`, the `@nats-io/nats-core` APIs are also made available.
42+
`@nats-io/transport-deno`, the `@nats-io/nats-core` APIs are also made
43+
available.
4344

4445
Your library selection process will start by selecting your runtime, and
4546
importing any additional functionality you may be interested in. The

obj/deno.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/obj",
3-
"version": "3.0.0-34",
3+
"version": "3.0.0-36",
44
"exports": {
55
".": "./src/mod.ts",
66
"./internal": "./src/internal_mod.ts"
@@ -33,8 +33,8 @@
3333
"test": "deno test -A --parallel --reload --quiet tests/ --import-map=import_map.json"
3434
},
3535
"imports": {
36-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
37-
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-38",
36+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
37+
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-40",
3838
"js-sha256": "npm:[email protected]"
3939
}
4040
}

obj/import_map.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"imports": {
3-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
4-
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-51/internal",
5-
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-38",
6-
"@nats-io/jetstream/internal": "jsr:@nats-io/jetstream@~3.0.0-38/internal",
3+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
4+
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-54/internal",
5+
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-40",
6+
"@nats-io/jetstream/internal": "jsr:@nats-io/jetstream@~3.0.0-40/internal",
77
"test_helpers": "../test_helpers/mod.ts",
88
"@nats-io/nkeys": "jsr:@nats-io/nkeys@~2.0.2",
99
"@nats-io/nuid": "jsr:@nats-io/nuid@~2.0.3",

obj/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/obj",
3-
"version": "3.0.0-34",
3+
"version": "3.0.0-36",
44
"files": [
55
"lib/",
66
"LICENSE",
@@ -33,8 +33,8 @@
3333
},
3434
"description": "obj library - this library implements all the base functionality for NATS objectstore for javascript clients",
3535
"dependencies": {
36-
"@nats-io/jetstream": "3.0.0-38",
37-
"@nats-io/nats-core": "3.0.0-51",
36+
"@nats-io/jetstream": "3.0.0-40",
37+
"@nats-io/nats-core": "3.0.0-54",
3838
"js-sha256": "^0.11.0"
3939
},
4040
"devDependencies": {

services/deno.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/services",
3-
"version": "3.0.0-26",
3+
"version": "3.0.0-28",
44
"exports": {
55
".": "./src/mod.ts",
66
"./internal": "./src/internal_mod.ts"
@@ -33,6 +33,6 @@
3333
"test": "deno test -A --parallel --reload --quiet tests/ --import-map=import_map.json"
3434
},
3535
"imports": {
36-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51"
36+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54"
3737
}
3838
}

services/import_map.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"imports": {
3-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
4-
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-51/internal",
3+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
4+
"@nats-io/nats-core/internal": "jsr:@nats-io/nats-core@~3.0.0-54/internal",
55
"test_helpers": "../test_helpers/mod.ts",
66
"@nats-io/nkeys": "jsr:@nats-io/nkeys@~2.0.2",
77
"@nats-io/nuid": "jsr:@nats-io/nuid@~2.0.3",

services/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/services",
3-
"version": "3.0.0-26",
3+
"version": "3.0.0-28",
44
"files": [
55
"lib/",
66
"LICENSE",
@@ -33,7 +33,7 @@
3333
},
3434
"description": "services library - this library implements all the base functionality for NATS services for javascript clients",
3535
"dependencies": {
36-
"@nats-io/nats-core": "3.0.0-51"
36+
"@nats-io/nats-core": "3.0.0-54"
3737
},
3838
"devDependencies": {
3939
"@types/node": "^22.10.10",

transport-deno/deno.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/transport-deno",
3-
"version": "3.0.0-22",
3+
"version": "3.0.0-24",
44
"exports": {
55
".": "./src/mod.ts"
66
},
@@ -20,7 +20,7 @@
2020
},
2121
"imports": {
2222
"@std/io": "jsr:@std/[email protected]",
23-
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-51",
23+
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-54",
2424
"@nats-io/nkeys": "jsr:@nats-io/nkeys@~2.0.2",
2525
"@nats-io/nuid": "jsr:@nats-io/nuid@~2.0.3"
2626
}

transport-deno/src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// This file is generated - do not edit
2-
export const version = "3.0.0-22";
2+
export const version = "3.0.0-24";

transport-node/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/transport-node",
3-
"version": "3.0.0-36",
3+
"version": "3.0.0-38",
44
"description": "Node.js client for NATS, a lightweight, high-performance cloud native messaging system",
55
"keywords": [
66
"nats",
@@ -55,14 +55,14 @@
5555
"node": ">= 18.0.0"
5656
},
5757
"dependencies": {
58-
"@nats-io/nats-core": "3.0.0-51",
58+
"@nats-io/nats-core": "3.0.0-54",
5959
"@nats-io/nkeys": "2.0.2",
6060
"@nats-io/nuid": "2.0.3"
6161
},
6262
"devDependencies": {
63-
"@nats-io/jetstream": "3.0.0-38",
64-
"@nats-io/kv": "3.0.0-32",
65-
"@nats-io/obj": "3.0.0-34",
63+
"@nats-io/jetstream": "3.0.0-40",
64+
"@nats-io/kv": "3.0.0-34",
65+
"@nats-io/obj": "3.0.0-36",
6666
"@types/node": "^22.10.10",
6767
"minimist": "^1.2.8",
6868
"shx": "^0.3.3",

transport-node/src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// This file is generated - do not edit
2-
export const version = "3.0.0-36";
2+
export const version = "3.0.0-38";

transport-node/tests/reconnect_test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,56 @@ const { describe, it } = require("node:test");
1616
const assert = require("node:assert").strict;
1717
const {
1818
connect,
19+
wsconnect,
1920
} = require("../index");
2021
const { NatsServer } = require("./helpers/launcher");
2122
const {
2223
createInbox,
2324
deferred,
25+
delay,
2426
} = require("@nats-io/nats-core/internal");
2527
const { Lock } = require("./helpers/lock");
2628

29+
describe("websocket reconnect", { timeout: 20_000, forceExit: true }, () => {
30+
it("reconnect websocket - disconnect reconnects", async () => {
31+
let srv = await NatsServer.start({
32+
logfile: "/tmp/nats-server.log",
33+
websocket: {
34+
port: -1,
35+
no_tls: true,
36+
},
37+
});
38+
39+
const d = deferred();
40+
const nc = await wsconnect({
41+
debug: true,
42+
servers: [`ws://127.0.0.1:${srv.websocket}`],
43+
});
44+
45+
const port = srv.websocket;
46+
(async () => {
47+
for await (const e of nc.status()) {
48+
if (e.type === "reconnect") {
49+
d.resolve();
50+
}
51+
}
52+
})();
53+
54+
await delay(1000);
55+
await srv.stop();
56+
srv = await NatsServer.start({
57+
websocket: {
58+
port,
59+
no_tls: true,
60+
},
61+
});
62+
63+
await d;
64+
await nc.close();
65+
await srv.stop();
66+
});
67+
});
68+
2769
describe(
2870
"reconnect",
2971
{ timeout: 20_000, concurrency: true, forceExit: true },

0 commit comments

Comments
 (0)