Skip to content

Commit b132967

Browse files
committed
Address comments
1 parent ad52946 commit b132967

4 files changed

Lines changed: 42 additions & 53 deletions

File tree

demo/web/javascript/README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ node runtime.mjs
2020
# also http://localhost:9001/capability/subscribe/<name> (SSE)
2121
```
2222

23-
`runtime.mjs` exposes a tiny `/add_two_ints` service + 1 Hz
24-
`/web_demo_tick` publisher so every panel has live data.
23+
`runtime.mjs` exposes a tiny `/add_two_ints` service and the shared
24+
`/web_demo_chatter` talker/listener topic (publish from one panel,
25+
receive in the others).
2526

2627
**Shell 2 — static-file server (hosts `index.html` + maps `/sdk/*` to
2728
the in-repo [`web/`](../../../web/) folder so the page can `import`
@@ -46,7 +47,7 @@ Open <http://localhost:8080/> in any modern browser. Runtime in shell
4647
const reply = await ros.call('/add_two_ints', { a: '2n', b: '40n' });
4748
console.log(reply.sum); // '42n'
4849
49-
await ros.subscribe('/web_demo_tick', (msg) => render(msg.data));
50+
await ros.subscribe('/web_demo_chatter', (msg) => render(msg.data));
5051
await ros.publish('/web_demo_chatter', { data: 'hi' });
5152
</script>
5253
```
@@ -71,12 +72,12 @@ so `subscribe` is reachable over HTTP as a `text/event-stream` — useful for
7172
clients that can't hold a WebSocket open:
7273

7374
```bash
74-
curl -N http://localhost:9001/capability/subscribe/web_demo_tick
75+
curl -N http://localhost:9001/capability/subscribe/web_demo_chatter
7576
# event: ready
76-
# data: {"capability":"/web_demo_tick","subId":"sse"}
77+
# data: {"capability":"/web_demo_chatter","subId":"sse"}
7778
#
7879
# event: message
79-
# data: {"data":"tick 0 @ 2026-06-12T…"}
80+
# data: {"data":"hi from curl"}
8081
# …one `message` event per published sample, until you ^C
8182
```
8283

@@ -85,7 +86,7 @@ Browser apps should still prefer the WebSocket transport for `subscribe`
8586
curl / AI-agent / server-side persona.
8687

8788
The page also has a **native `EventSource` panel** (section 6) that
88-
subscribes to `/web_demo_tick` over the same SSE endpoint — no SDK, no
89+
subscribes to `/web_demo_chatter` over the same SSE endpoint — no SDK, no
8990
WebSocket, just the browser primitive over plain HTTP. Because the page
9091
(`:8080`) and the HTTP transport (`:9001`) are different origins, the
9192
demo's `runtime.mjs` enables CORS (`new HttpTransport({ sse: true, cors:
@@ -94,10 +95,10 @@ pass your site's origin instead of `true`.
9495

9596
### Pair it with the stock publisher example
9697

97-
The EventSource panel's topic box defaults to `/web_demo_tick`, but the
98-
runtime also exposes `/topic` so you can feed the demo from your own
99-
node instead of the built-in tick loop. In a third shell, run the
100-
standard publisher example:
98+
The EventSource panel's topic box defaults to `/web_demo_chatter` (the
99+
shared demo topic), but the runtime also exposes `/topic` so you can
100+
feed the demo from your own node. In a third shell, run the standard
101+
publisher example:
101102

102103
```bash
103104
source /opt/ros/<distro>/setup.bash
@@ -124,12 +125,11 @@ web runtime against your own publishers.
124125
## Without the bundled `runtime.mjs`
125126

126127
`runtime.mjs` bundles the rclnodejs/web runtime and the demo's sample
127-
ROS 2 nodes (the `/add_two_ints` service + the `/web_demo_tick`
128-
publisher) into one process so the demo runs out of the box. In a
129-
real project you already have those ROS 2 nodes running elsewhere,
130-
so you only need the runtime. **Replace shell 1's `node runtime.mjs`
131-
with the CLI** — shell 2 (`node static.mjs`) and the browser code are
132-
unchanged:
128+
ROS 2 nodes (the `/add_two_ints` service) into one process so the demo
129+
runs out of the box. In a real project you already have those ROS 2
130+
nodes running elsewhere, so you only need the runtime. **Replace shell
131+
1's `node runtime.mjs` with the CLI** — shell 2 (`node static.mjs`) and
132+
the browser code are unchanged:
133133

134134
```bash
135135
# shell 1 (instead of `node runtime.mjs`); the `-p rclnodejs` tells npx
@@ -138,7 +138,7 @@ npx -p rclnodejs rclnodejs-web web.json
138138

139139
# the publisher / service the demo expects:
140140
ros2 run demo_nodes_cpp add_two_ints_server
141-
# (and a publisher of std_msgs/String on /web_demo_tick from any source)
141+
# (and a publisher of std_msgs/String on /web_demo_chatter from any source)
142142
```
143143

144144
> Note: this demo enables the SSE subscribe endpoint programmatically in

demo/web/javascript/index.html

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ <h2>1. Service call — <code>/add_two_ints</code></h2>
193193
console.log(reply.sum); <span class="com">// '42n'</span></pre>
194194
</div>
195195

196-
<h2>2. Topic subscription — <code>/web_demo_tick</code></h2>
196+
<h2>2. Topic subscription — <code>/web_demo_chatter</code></h2>
197197
<div class="panel">
198198
<div class="controls">
199199
<div class="row">
@@ -208,8 +208,9 @@ <h2>2. Topic subscription — <code>/web_demo_tick</code></h2>
208208

209209
<span class="kw">const</span> ros = <span class="kw">await</span> connect(<span class="str">'ws://localhost:9000/capability'</span>);
210210

211-
<span class="com">// The server publishes /web_demo_tick once a second.</span>
212-
<span class="kw">const</span> sub = <span class="kw">await</span> ros.<span class="kw">subscribe</span>(<span class="str">'/web_demo_tick'</span>, (msg) =&gt; {
211+
<span class="com">// /web_demo_chatter is the shared demo topic — anything panel 3</span>
212+
<span class="com">// (or curl) publishes to it lands here, since it's the same topic.</span>
213+
<span class="kw">const</span> sub = <span class="kw">await</span> ros.<span class="kw">subscribe</span>(<span class="str">'/web_demo_chatter'</span>, (msg) =&gt; {
213214
console.log(<span class="str">'recv:'</span>, msg.data);
214215
});
215216

@@ -295,12 +296,12 @@ <h2>5. Same capability, no SDK — just <code>curl</code></h2>
295296

296297
<span class="com"># subscribe over SSE — streams text/event-stream until you ^C</span>
297298
<span class="com"># (-N disables curl's buffering so events print as they arrive)</span>
298-
curl -N http://localhost:9001/capability/subscribe/web_demo_tick
299+
curl -N http://localhost:9001/capability/subscribe/web_demo_chatter
299300
<span class="com"># event: ready</span>
300-
<span class="com"># data: {"capability":"/web_demo_tick","subId":"sse"}</span>
301+
<span class="com"># data: {"capability":"/web_demo_chatter","subId":"sse"}</span>
301302
<span class="com">#</span>
302303
<span class="com"># event: message</span>
303-
<span class="com"># data: {"data":"tick 0 @ 2026-06-12T…"}</span>
304+
<span class="com"># data: {"data":"hi from curl"}</span>
304305
<span class="com"># …one `message` event per published sample…</span>
305306

306307
<span class="com"># allow-list rejection — returns 404 + structured error body</span>
@@ -322,22 +323,19 @@ <h2>
322323
section 2 is still the better fit.
323324
</p>
324325
<p style="font-size: 0.9em; color: #555">
325-
The topic box defaults to <code>/web_demo_tick</code> (the demo's
326-
built-in tick loop). It is also wired to <code>/topic</code> so you can
327-
feed the demo from the stock publisher example instead — run
328-
<code
329-
>node ../../../example/topics/publisher/publisher-example.mjs</code
330-
>
331-
in another shell, set the box to <code>/topic</code>, and watch your own
332-
node's messages stream in.
326+
The topic box defaults to <code>/web_demo_chatter</code> — the same
327+
topic panels 2 and 3 use, so a publish from panel 3 streams in here at
328+
the same time it reaches the WebSocket subscriber. Point the box at
329+
<code>/topic</code> instead to subscribe to an external ROS 2 publisher
330+
(see the README's <em>publisher example</em> pairing).
333331
</p>
334332
<div class="panel">
335333
<div class="controls">
336334
<div class="row">
337335
<input
338336
id="sseTopic"
339337
type="text"
340-
value="/web_demo_tick"
338+
value="/web_demo_chatter"
341339
spellcheck="false"
342340
aria-label="topic to subscribe to"
343341
/>
@@ -349,9 +347,9 @@ <h2>
349347
<pre
350348
class="code"
351349
><span class="com">// No import — EventSource is built into every browser.</span>
352-
<span class="com">// Swap the topic for '/topic' to pair with publisher-example.mjs.</span>
350+
<span class="com">// '/web_demo_chatter' is the shared demo topic; use '/topic' to pair with publisher-example.mjs.</span>
353351
<span class="kw">const</span> es = <span class="kw">new</span> EventSource(
354-
<span class="str">'http://localhost:9001/capability/subscribe/web_demo_tick'</span>,
352+
<span class="str">'http://localhost:9001/capability/subscribe/web_demo_chatter'</span>,
355353
);
356354

357355
es.addEventListener(<span class="str">'ready'</span>, (e) =&gt;
@@ -472,7 +470,7 @@ <h2>
472470
subBtn.onclick = async () => {
473471
if (!ros) return;
474472
try {
475-
tickSub = await ros.subscribe('/web_demo_tick', (msg) =>
473+
tickSub = await ros.subscribe('/web_demo_chatter', (msg) =>
476474
log('tickLog', msg.data)
477475
);
478476
subBtn.disabled = true;
@@ -537,7 +535,7 @@ <h2>
537535
sseBtn.onclick = () => {
538536
closeEs();
539537
// Accept '/topic' or 'topic'; the URL path carries the bare name.
540-
const name = (sseTopic.value || '/web_demo_tick')
538+
const name = (sseTopic.value || '/web_demo_chatter')
541539
.trim()
542540
.replace(/^\//, '');
543541
const url = `${ENDPOINTS.http}/capability/subscribe/${encodeURIComponent(

demo/web/javascript/runtime.mjs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function displayHost(host) {
3838
// Render the registry as a small human-readable table:
3939
// call /add_two_ints example_interfaces/srv/AddTwoInts
4040
// publish /web_demo_chatter std_msgs/msg/String
41-
// subscribe /web_demo_tick std_msgs/msg/String
41+
// subscribe /web_demo_chatter std_msgs/msg/String
4242
function formatCapabilities(caps) {
4343
const rows = [];
4444
for (const verb of ['call', 'publish', 'subscribe']) {
@@ -69,17 +69,6 @@ node.createService(
6969
}
7070
);
7171

72-
// A real ROS 2 publisher producing a tick once a second so the
73-
// browser's subscribe() has something to receive without the user
74-
// having to publish first.
75-
const tickPub = node.createPublisher('std_msgs/msg/String', '/web_demo_tick');
76-
let counter = 0;
77-
setInterval(() => {
78-
tickPub.publish({
79-
data: `tick ${counter++} @ ${new Date().toISOString()}`,
80-
});
81-
}, 1000);
82-
8372
rclnodejs.spin(node);
8473

8574
// ---- Layer 2 + 3: capability runtime over WebSocket *and* HTTP -------
@@ -116,10 +105,12 @@ runtime.expose({
116105
call: { '/add_two_ints': 'example_interfaces/srv/AddTwoInts' },
117106
publish: { '/web_demo_chatter': 'std_msgs/msg/String' },
118107
subscribe: {
119-
'/web_demo_tick': 'std_msgs/msg/String',
108+
// Shared talker/listener topic: panels 2 (WebSocket), 3 (round-trip),
109+
// and 6 (SSE) all use it — so a browser publish is visible across
110+
// every subscriber at once.
120111
'/web_demo_chatter': 'std_msgs/msg/String',
121112
// Pairs with the stock publisher example so developers can feed the
122-
// demo from their own node instead of the built-in tick loop:
113+
// demo from their own node:
123114
// node ../../../example/topics/publisher/publisher-example.mjs
124115
// then subscribe to `/topic` from the browser / curl / EventSource.
125116
'/topic': 'std_msgs/msg/String',

demo/web/javascript/web.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
"/web_demo_chatter": "std_msgs/msg/String"
1616
},
1717
"subscribe": {
18-
"/web_demo_tick": "std_msgs/msg/String",
19-
"/web_demo_chatter": "std_msgs/msg/String"
18+
"/web_demo_chatter": "std_msgs/msg/String",
19+
"/topic": "std_msgs/msg/String"
2020
}
2121
}
2222
}

0 commit comments

Comments
 (0)