Commit d283968
TCP / WebSocket connection option
Adds a third connect transport alongside Web Bluetooth and Web
Serial: WebSocket to a local or remote rnsd via a small Python
bridge. This unlocks Safari, Firefox, and iOS (none of which have
Web Bluetooth or Web Serial) and lets the web client join a
Reticulum network via any backbone rnsd is configured to reach,
not just a local RNode's LoRa radio.
Architecture. Browsers cannot open raw TCP sockets so "TCP"
really means WebSocket to a bridge that forwards bytes to rnsd's
TCPServerInterface. All Reticulum protocol logic continues to run
in the browser; the bridge and rnsd are only a transport. Identity
stays in IndexedDB in the browser — the bridge never sees private
keys.
js/hdlc.js: HDLC frame encode/decode (0x7E flag, 0x7D escape,
0x20 mask) matching RNS TCPInterface. Streaming parser across
arbitrary chunk boundaries. Separate from kiss.js because the
framing bytes and command-byte semantics are different.
js/websocket-transport.js: WebSocket byte-stream mirroring the
shape of ble-transport.js and serial-transport.js. Binary mode,
emits each received ArrayBuffer up to the parser, ignores text
messages, wires close events through to the interface layer.
js/rnsd-interface.js: wraps WebSocketTransport + HdlcParser and
exposes the same {connect, disconnect, sendPacket, _onPacket,
_onLog} shape as rnode.js so app.js can drive either without
branching. Exposes a capabilities flag {rnodeControl: false,
radioConfig: false} that app.js consumes to skip the RNode
command sequence and the radio-config panel on the WebSocket
path. Stubs out detect / getFirmwareVersion / getBattery /
configureAndStart so any forgotten caller still works.
js/app.js: adds a 'ws' transport type to connect(), a new
markInterfaceReady() helper that fires the startup auto-announce,
the periodic announce timer, and the outbound retry tick, shared
between the RNode path (called from startRadio when the radio
reports on) and the WebSocket path (called immediately after the
socket opens). startRadio is simplified to call markInterfaceReady
instead of inlining the setup. New btn-connect-ws event handler,
browser-capability check for typeof WebSocket, disconnect cleanup
for the new button and URL field.
index.html: new "Connect (WebSocket)" button and a URL field that
defaults to ws://localhost:7878.
tools/ws_bridge.py: async Python bridge, ~140 lines. Accepts
WebSocket connections on ws://localhost:7878 by default, opens a
fresh TCP connection to tcp://localhost:4242 per WS client, and
copies bytes in both directions without parsing HDLC frames
(rnsd's TCP interface and our HdlcParser both handle streaming).
CLI flags for --ws-host / --ws-port / --rnsd-host / --rnsd-port.
Requires 'pip install websockets', everything else is stdlib
asyncio.
README.md: extensive new "TCP (WebSocket) connection" section
covering the architecture, step-by-step setup (install rnsd,
configure TCPServerInterface, install websockets, start the
bridge, connect from the client), the mixed-content caveat with
three workarounds (localhost, wss:// with a cert, reverse
proxy), security notes (browser owns identity, bridge is a dumb
forwarder, don't expose plain ws:// publicly), and troubleshooting
for the usual failure modes. Updates the platform support table
to show WebSocket as universally supported, updates the
architecture diagram to show both transport paths, adds
websocket-transport.js / hdlc.js / rnsd-interface.js to the
module layout, and adds ws_bridge.py to the tools list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent bb1dc20 commit d283968
7 files changed
Lines changed: 662 additions & 90 deletions
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
34 | 41 | | |
35 | 42 | | |
36 | 43 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
1057 | 1058 | | |
1058 | 1059 | | |
1059 | 1060 | | |
| 1061 | + | |
1060 | 1062 | | |
1061 | 1063 | | |
1062 | 1064 | | |
1063 | | - | |
1064 | | - | |
1065 | | - | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
1066 | 1077 | | |
1067 | 1078 | | |
1068 | 1079 | | |
| |||
1073 | 1084 | | |
1074 | 1085 | | |
1075 | 1086 | | |
1076 | | - | |
1077 | | - | |
1078 | | - | |
1079 | | - | |
1080 | | - | |
1081 | | - | |
1082 | | - | |
1083 | | - | |
1084 | | - | |
1085 | | - | |
1086 | | - | |
1087 | | - | |
1088 | | - | |
1089 | | - | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
1090 | 1113 | | |
1091 | 1114 | | |
1092 | 1115 | | |
1093 | 1116 | | |
1094 | 1117 | | |
| 1118 | + | |
1095 | 1119 | | |
1096 | 1120 | | |
1097 | 1121 | | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
1098 | 1145 | | |
1099 | 1146 | | |
| 1147 | + | |
1100 | 1148 | | |
1101 | 1149 | | |
1102 | 1150 | | |
| |||
1107 | 1155 | | |
1108 | 1156 | | |
1109 | 1157 | | |
| 1158 | + | |
| 1159 | + | |
1110 | 1160 | | |
1111 | 1161 | | |
1112 | 1162 | | |
| |||
1123 | 1173 | | |
1124 | 1174 | | |
1125 | 1175 | | |
1126 | | - | |
1127 | 1176 | | |
1128 | 1177 | | |
1129 | 1178 | | |
1130 | 1179 | | |
1131 | | - | |
1132 | | - | |
1133 | | - | |
1134 | | - | |
1135 | | - | |
1136 | | - | |
1137 | | - | |
1138 | | - | |
1139 | | - | |
1140 | | - | |
1141 | | - | |
1142 | | - | |
1143 | | - | |
1144 | | - | |
1145 | | - | |
1146 | | - | |
1147 | | - | |
1148 | | - | |
1149 | | - | |
1150 | | - | |
1151 | | - | |
1152 | | - | |
1153 | | - | |
1154 | | - | |
1155 | | - | |
1156 | | - | |
1157 | | - | |
1158 | | - | |
1159 | | - | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
1160 | 1183 | | |
1161 | 1184 | | |
1162 | 1185 | | |
| |||
1201 | 1224 | | |
1202 | 1225 | | |
1203 | 1226 | | |
1204 | | - | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
1205 | 1230 | | |
1206 | 1231 | | |
1207 | 1232 | | |
| |||
1210 | 1235 | | |
1211 | 1236 | | |
1212 | 1237 | | |
1213 | | - | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
1214 | 1243 | | |
1215 | 1244 | | |
1216 | 1245 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
0 commit comments