Skip to content

Commit d980d90

Browse files
Update Node binding and JS API for NUClearNet 2
Migrate the addon to NUClear::network::NUClearNet (protocol 0x03), wire typed event listeners through add/setSubscriptions, and release as 2.0.0. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 0623a32 commit d980d90

8 files changed

Lines changed: 297 additions & 138 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
Node.js module for interacting with the [NUClear](https://github.com/Fastcode/NUClear) network.
66

7+
## NUClearNet 2 (v2.0.0+)
8+
9+
Version 2 uses the redesigned **NUClearNet** library from [NUClear PR #190](https://github.com/Fastcode/NUClear/pull/190) (wire protocol **0x03**). It is **not** compatible with 1.x clients or NUClear builds that still use the old `NUClearNetwork` stack (protocol 0x02). Upgrade Node clients and NUClear robots together.
10+
11+
The vendored NUClear tree is updated via `git subtree` from the `houliston/nuclearnet-v2` branch (currently [NUClear@ce389fbf](https://github.com/Fastcode/NUClear/commit/ce389fbfea56ce97527474865dc343e0c087bd70)).
12+
13+
Peer join events may arrive slightly later than in 1.x because connection requires both multicast announce and a unicast CONNECT handshake.
14+
715
## Installation
816

917
The package contains a native module, so you'll need a working C++ compiler on your system to install and build it.

binding.gyp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@
66
'src/binding.cpp',
77
'src/NetworkBinding.cpp',
88
'src/NetworkListener.cpp',
9-
'src/nuclear/src/extension/network/NUClearNetwork.cpp',
10-
'src/nuclear/src/util/platform.cpp',
11-
'src/nuclear/src/util/network/get_interfaces.cpp',
12-
'src/nuclear/src/util/network/if_number_from_address.cpp',
9+
'src/nuclear/src/nuclearnet/Discovery.cpp',
10+
'src/nuclear/src/nuclearnet/Fragmentation.cpp',
11+
'src/nuclear/src/nuclearnet/NUClearNet.cpp',
12+
'src/nuclear/src/nuclearnet/PacketDeduplicator.cpp',
13+
'src/nuclear/src/nuclearnet/RTTEstimator.cpp',
14+
'src/nuclear/src/nuclearnet/Reliability.cpp',
15+
'src/nuclear/src/nuclearnet/Routing.cpp',
1316
'src/nuclear/src/util/network/resolve.cpp',
17+
'src/nuclear/src/util/platform.cpp',
1418
'src/nuclear/src/util/serialise/xxhash.cpp'
1519
],
1620
'cflags': [],
1721
'include_dirs': [
1822
'<!@(node -p "require(\'node-addon-api\').include")',
19-
'src/nuclear/src/include'
23+
'src/nuclear/src'
2024
],
2125
"defines": [
2226
# Restrict NAPI to v6 (to support Node v10)

index.js

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,23 @@ class NUClearNet extends EventEmitter {
3838
this.on('newListener', (event) => {
3939
this.assertNotDestroyed();
4040

41-
if (
42-
event !== 'nuclear_join' &&
43-
event !== 'nuclear_leave' &&
44-
event !== 'nuclear_packet' &&
45-
event !== 'newListener' &&
46-
event !== 'removeListener' &&
47-
event !== 'disconnect' &&
48-
this.listenerCount(event) === 0
49-
) {
41+
if (this._isTypedPacketEvent(event) && this.listenerCount(event) === 0) {
5042
const hash = this._net.hash(event);
5143
this._callbackMap[hash] = event;
44+
if (this._active) {
45+
this._net.addSubscription(hash);
46+
}
5247
}
5348
});
5449

5550
// We are no longer listening to this type
5651
this.on('removeListener', (event) => {
57-
// If we are no longer listening to this type
58-
if (
59-
event !== 'nuclear_join' &&
60-
event !== 'nuclear_leave' &&
61-
event !== 'nuclear_packet' &&
62-
event !== 'newListener' &&
63-
event !== 'removeListener' &&
64-
event !== 'disconnect' &&
65-
this.listenerCount(event) === 0
66-
) {
67-
// Get our hash and delete it
52+
if (this._isTypedPacketEvent(event) && this.listenerCount(event) === 0) {
6853
const hash = this._net.hash(event);
6954
delete this._callbackMap[hash];
55+
if (this._active) {
56+
this._syncSubscriptions();
57+
}
7058
}
7159
});
7260

@@ -147,6 +135,22 @@ class NUClearNet extends EventEmitter {
147135
}, duration);
148136
}
149137

138+
_isTypedPacketEvent(event) {
139+
return (
140+
event !== 'nuclear_join' &&
141+
event !== 'nuclear_leave' &&
142+
event !== 'nuclear_packet' &&
143+
event !== 'newListener' &&
144+
event !== 'removeListener' &&
145+
event !== 'disconnect'
146+
);
147+
}
148+
149+
_syncSubscriptions() {
150+
const hashes = Object.values(this._callbackMap).map((eventName) => this._net.hash(eventName));
151+
this._net.setSubscriptions(hashes);
152+
}
153+
150154
hash(data) {
151155
this.assertNotDestroyed();
152156
return this._net.hash(data);
@@ -164,6 +168,10 @@ class NUClearNet extends EventEmitter {
164168
const port = options.port === undefined ? 7447 : options.port;
165169
const mtu = options.mtu === undefined ? 1500 : options.mtu;
166170

171+
if (Object.keys(this._callbackMap).length > 0) {
172+
this._syncSubscriptions();
173+
}
174+
167175
// Connect to the network
168176
this._net.reset(name, address, port, mtu);
169177

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nuclearnet.js",
3-
"version": "1.7.2",
3+
"version": "2.0.0",
44
"description": "Node.js module for interacting with the NUClear network",
55
"main": "index.js",
66
"types": "index.d.ts",

0 commit comments

Comments
 (0)