Skip to content

NUClearNet 2 (protocol 0x03) - #29

Open
TrentHouliston wants to merge 21 commits into
mainfrom
houliston/nuclearnet-v2
Open

NUClearNet 2 (protocol 0x03)#29
TrentHouliston wants to merge 21 commits into
mainfrom
houliston/nuclearnet-v2

Conversation

@TrentHouliston

@TrentHouliston TrentHouliston commented Jun 3, 2026

Copy link
Copy Markdown
Member

Summary

  • Refresh the vendored NUClear tree via git subtree from houliston/nuclearnet-v2 (NUClear PR #190, commit ce389fbf)
  • Replace the old NUClearNetwork addon build with the standalone src/nuclearnet library
  • Update NetworkBinding for the new NUClear::network::NUClearNet API (handshake, protocol 0x03)
  • Sync typed on('message.type') listeners with addSubscription / setSubscriptions (same pattern as NUClear NetworkController)
  • Bump package version to 2.0.0 (breaking change: not interoperable with 1.x / old NUClear robots on protocol 0x02)

Test plan

  • npm run build (macOS)
  • npm test — 10/10 passing locally
  • CI matrix (Linux / Windows / macOS, Node 18/20)
  • Interop smoke test with a NUClear build from PR #190 on the same multicast group

Made with Cursor

Native logs go to the JavaScript logger

The library's own log messages went straight to stderr while the binding's messages went through console.error with a [NUClearNet.js] prefix, so turning debug on produced two differently formatted streams and the native half ignored any redirection of console.

NUClear now lets an embedder install a log handler, so NetworkBinding gains an onLog callback (following the same ThreadSafeFunction pattern as onPacket/onJoin) and index.js funnels the native messages through the same _log path as everything else, tagged with the component they came from:

[NUClearNet.js] debug handshake 10.51.2.138:37064 IDLE -> SYN_SENT (sent SYN) { component: 'discovery' }

The debug option and NUCLEARNET_DEBUG continue to gate both halves, and the handler is removed on destroy() so nothing can call back into a released function.

TrentHouliston and others added 5 commits June 3, 2026 15:46
Co-authored-by: Cursor <cursoragent@cursor.com>
git-subtree-dir: src/nuclear
git-subtree-split: ce389fbfea56ce97527474865dc343e0c087bd70
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>
Patch NUClearNet send_buf for MSVC WSABUF fields, link ws2_32 on Windows,
skip multicast-dependent tests on GitHub macOS runners, and add a Docker
Linux test path plus workflow job.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread src/NetworkBinding.cpp
uint32_t port = arg_port.IsNumber() ? arg_port.As<Napi::Number>().Uint32Value() : 7447;
uint32_t network_mtu = arg_mtu.IsNumber() ? arg_mtu.As<Napi::Number>().Uint32Value() : 1500;
network::NetworkConfig config;
config.announce_address = "239.226.152.162";
Comment thread src/nuclear/src/nuclearnet/NUClearNet.hpp Fixed
}

// Then verify multicast actually works with a real round-trip
return test_multicast_roundtrip(AF_INET, "239.255.255.250");
}

// Then verify multicast actually works with a real round-trip
return test_multicast_roundtrip(AF_INET6, "ff02::1");
NetworkConfig make_config(const std::string& name) {
NetworkConfig config;
config.name = name;
config.announce_address = "239.226.152.162";
TrentHouliston and others added 9 commits June 3, 2026 16:04
Use a make_iovec helper for WSABUF initialization, call NUClear::sendmsg on
Windows, and omit msg_flags where WSAMSG has no flags member.

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce Log.hpp/Log.cpp with off-through-trace levels, instrument
Discovery and NUClearNet for handshake and wire events, and expose
setLogLevel through the Node binding plus JS connect/debug options.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pull in NUClear@c1bf7d4 (debug logging on current houliston/nuclearnet-v2)
including socket rebind and existing WSABUF/sendmsg Windows build support.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pull PR #190 review fixes: fragment validation, Discovery/Reliability
hardening, LogLevel/MSVC CI fixes, and related nuclearnet updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Ignore own announces by matching the data socket ephemeral port, fix
getaddrinfo iteration to use each result entry, and enable IP_MULTICAST_LOOP
for single-host multicast development.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wire socket_change_callback to replace listener workers with generation
tracking, stop stale FD polling on shutdown/reset/destroy, and schedule
restarts on the main thread via ThreadSafeFunction.

Co-authored-by: Cursor <cursoragent@cursor.com>
Run integration tests against both default multicast and 127.0.0.1, skip
loopback on macOS where SO_REUSEPORT load-balances unicast, and add a
reconnect lifecycle test.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread tests/test.js
const loopbackTestsSupported = process.platform !== 'darwin';

const networkModes = [
{ label: 'multicast', address: '239.226.152.162', supported: multicastTestsSupported },
Trent Houliston and others added 2 commits August 14, 2026 01:12
The library wrote its logs straight to stderr while our own messages went
through console.error with a [NUClearNet.js] prefix, so turning debug on
gave you two differently formatted streams and the native half ignored
any redirection of console.

NUClear now lets an embedder install a log handler, so hand the native
messages to the same _log path as everything else. The component the
message came from is included as a field.

Also syncs the vendored nuclear subtree from NUClear@b7caa31c, which
brings in the log handler along with the SO_REUSEADDR/SO_REUSEPORT
pairing and member initializer changes made since 18c2877b.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picks up the explicit log level dispatch in NetworkController.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread Dockerfile
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci
uses: astral-sh/setup-uv@v4

- name: Install dependencies
run: uv sync --group dev
uses: astral-sh/setup-uv@v4

- name: Install dependencies
run: uv sync --group dev
run: uv sync --group dev

- name: Check markdown formatting
run: uv run mdformat --check docs/
run: uv sync --group dev

- name: Check markdown formatting
run: uv run mdformat --check docs/
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee /etc/apt/sources.list.d/llvm-15
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee -a /etc/apt/sources.list.d/llvm-15
echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" | sudo tee /etc/apt/sources.list.d/llvm-19.list
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee /etc/apt/sources.list.d/llvm-15
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee -a /etc/apt/sources.list.d/llvm-15
echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" | sudo tee /etc/apt/sources.list.d/llvm-19.list
echo "deb-src http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" | sudo tee -a /etc/apt/sources.list.d/llvm-19.list
Trent Houliston and others added 5 commits August 14, 2026 04:38
Picks up the fix for data packets with an empty payload being rejected
as short, which affects any message that serialises to zero bytes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picks up bounded retransmission with backoff, acknowledging packets
discarded for not being subscribed, and larger socket buffers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An unacknowledged reliable send now disconnects the peer rather than
silently dropping the data, so a nuclear_leave is emitted where the
message would previously have gone missing without any indication.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A peer whose data socket lands on the same ephemeral port as ours is no
longer mistaken for our own announce coming back, which had made that one
peer invisible while every other peer worked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Data is no longer sent to a peer before its handshake completes, which
had made the first messages after discovery undeliverable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants