Dial a WebSocket link (TypeScript)¶
TransportWs dials a WebSocket listener, and each libtracer frame crosses as one BINARY
message. The listener here is a loopback ws server on port 0 in front of the stand-in node.
The node on the other end is
stand-in-node.mjs,
an in-memory stand-in. The TypeScript packages have no node of their own, and the stand-in lets
the example run with no C++ build. Against a real node the client code is unchanged.
What to notice¶
connect()resolves when the socket is open. Only then can frames cross. The client code is the same as in the in-memory examples.Port 0, read back. The kernel picks the port and the example reads it from the listener, so nothing collides with whatever else runs on the machine.
A browser dials the same way. On a runtime with a global
WebSocket(a browser, or Node 22 and later) the{ WebSocket }option can be left out.
Source¶
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2026 avatarsd LLC
3
4/**
5 * @file
6 * @brief One concept: dial a link. `TransportWs` dials a WebSocket listener and carries one
7 * libtracer frame per BINARY message; the client on top is the same one the in-memory
8 * examples use.
9 *
10 * Run: `node examples/ws-dial.mjs` (from `bindings/typescript/`, after `npm run build`).
11 */
12
13import assert from 'node:assert/strict';
14import { WebSocketServer, WebSocket } from 'ws';
15import { TransportWs } from '@avatarsd-llc/libtracer-ws';
16import { LibtracerClient, encodeValue } from '@avatarsd-llc/libtracer-client';
17import { standInNode } from './stand-in-node.mjs';
18
19// LISTEN: a loopback listener on port 0 (the kernel picks), fronting the stand-in node.
20const node = standInNode();
21const wss = new WebSocketServer({ host: '127.0.0.1', port: 0 });
22await new Promise((resolve) => wss.once('listening', resolve));
23wss.on('connection', (sock) =>
24 sock.on('message', (data) => node.handle(new Uint8Array(data), (b) => sock.send(b, { binary: true }))),
25);
26const url = `ws://127.0.0.1:${wss.address().port}`;
27
28// DIAL: connect() resolves once the WebSocket is open; only then can frames cross.
29const transport = new TransportWs(url, { WebSocket });
30await transport.connect();
31console.log(`dialled ${url}`);
32
33const client = new LibtracerClient(transport);
34await client.write('/sensor/temp', encodeValue(Uint8Array.of(42)));
35assert.equal((await client.read('/sensor/temp')).payload[0], 42);
36console.log('write + read crossed the socket');
37
38await transport.close();
39await new Promise((resolve) => wss.close(resolve));
Run it from bindings/typescript/, after npm ci && npm run build:
$ node examples/ws-dial.mjs
See also: DIAL and LISTEN (C++) · the WebSocket upgrade (C++).