+ setWsjtxMulticastEnabled(e.target.checked)}
+ style={{ marginRight: '8px' }}
+ />
+ Use multicast address
+ setWsjtxMulticastAddress(e.target.value.toUpperCase())}
+ style={{
+ width: '10%',
+ marginLeft: '8px',
+ padding: '8px 12px',
+ background: 'var(--bg-primary)',
+ border: '1px solid var(--border-color)',
+ borderRadius: '4px',
+ color: wsjtxMulticastEnabled ? 'var(--text-primary)' : 'var(--text-secondary',
+ fontSize: '12px',
+ fontFamily: 'JetBrains Mono, monospace',
+ boxSizing: 'border-box',
+ }}
+ />
+ If you are going to run a wsjt-x relay, define here if you need a multicast listener and what address it
+ should be using.
+
+
+
{/* Rig Control Settings */}
);
diff --git a/src/utils/config.js b/src/utils/config.js
index 7ff71e2b..d10b6d8f 100644
--- a/src/utils/config.js
+++ b/src/utils/config.js
@@ -65,6 +65,7 @@ export const DEFAULT_CONFIG = {
dxClusterSource: 'dxspider-proxy',
customDxCluster: { enabled: false, host: '', port: 7300 },
udpDxCluster: { host: '', port: 12060 },
+ wsjtxRelayMulticast: { enabled: false, address: '224.0.0.1' },
};
// Cache for server config
diff --git a/wsjtx-relay/README.md b/wsjtx-relay/README.md
index ccbbbc91..12ce3ac6 100644
--- a/wsjtx-relay/README.md
+++ b/wsjtx-relay/README.md
@@ -6,42 +6,65 @@ WSJT-X sends decoded FT8/FT4/JT65/WSPR messages via UDP, which only works on the
## How It Works
-```
+```text
WSJT-X ──UDP──► relay.js (your PC) ──HTTPS──► openhamclock.com
port 2237 /api/wsjtx/relay
```
## Quick Start
-### 1. Get Your Relay Key
+This assumes that you are loading Openhamclock from a server that is configured to provide a WSJT-X relay. See [the main README](../README.md#wsjt-x-relay-agent) if you need to configure a relay in your own server.
-On your OpenHamClock server, set the `WSJTX_RELAY_KEY` environment variable:
+### 1. Configure Openhamclock to use multicast if you need it
-```bash
-# In .env file or docker-compose environment:
-WSJTX_RELAY_KEY=your-secret-key-here
-```
+If you have more than one listening application on your system, you will need to configure wsjt-x to use multicast, as well as all of the listener applications.
+For Openhamclock, in the `Station Settings` enable `Use multicast address`. If you are using an address other than the default, you should also set that.
-Pick any strong random string. This authenticates the relay so only your agent can push decodes to your server.
+### 2. Download the relay command
-### 2. Run the Relay
+In the WSJT-X tab of the PSK Reporter, you will see a screen with buttons to download the relay comand. If you have configured to use multicast for this, the address will be noted in this tab. Select the button that is labelled with the Operatng System that you are running. This will download a script that will start the relay to your Downloads folder.
-On the machine running WSJT-X:
+### 3. Download node.js
+
+You will need `node.js` to be able to run the relay. To do this
+
+| Operating System. | Instruction |
+| -------------------- | ---------------------------------------------- |
+| Ubuntu/Debian. | `sudo apt install nodejs` |
+| Fedora | `sudo dnf install nodejs` |
+| Mac (using homebrew) | `brew install node` |
+| Windows | The batch script will download it if necessary |
+
+### 4. Start the relay
+
+#### Linux
```bash
-# Download just this folder (or copy it from the repo)
-node relay.js --url https://openhamclock.com --key your-secret-key-here
+chmod +x start-relay.sh
+./start-relay.sh
```
-Or with environment variables:
+#### Mac
```bash
-export OPENHAMCLOCK_URL=https://openhamclock.com
-export RELAY_KEY=your-secret-key-here
-node relay.js
+chmod +x start-relay.command
+./start-relay.command
```
-### 3. Configure WSJT-X
+#### Windows
+
+## Enabling the Relay on your server
+
+On your OpenHamClock server, set the `WSJTX_RELAY_KEY` environment variable:
+
+```bash
+# In .env file or docker-compose environment:
+WSJTX_RELAY_KEY=your-secret-key-here
+```
+
+Pick any strong random string. This authenticates the relay so only your agent can push decodes to your server.
+
+## Configure WSJT-X
In WSJT-X:
@@ -51,25 +74,18 @@ In WSJT-X:
- Port: `2237`
- ☑ Accept UDP requests
+ Note that if you are using multicast, you should use a multicast address (like `224.0.0.1`) for the address.
+
That's it. The relay will show decoded messages as they come in.
## Requirements
- **Node.js 14+** (no npm install needed — zero dependencies)
- WSJT-X, JTDX, or any software that speaks the WSJT-X UDP protocol
-- Network access to your OpenHamClock server
-
-## Options
-| Flag | Env Variable | Default | Description |
-| ------------ | ------------------ | ------- | ------------------------- |
-| `--url` | `OPENHAMCLOCK_URL` | — | Server URL (required) |
-| `--key` | `RELAY_KEY` | — | Auth key (required) |
-| `--port` | `WSJTX_UDP_PORT` | `2237` | Local UDP port |
-| `--interval` | `BATCH_INTERVAL` | `2000` | Batch send interval (ms) |
-| `--verbose` | `VERBOSE=true` | off | Show all decoded messages |
+-- ## Running as a Service
-## Running as a Service
+Note, if you want the relay to listen to a multicast group, you need to include the line mentioning `MULTICAST`, and replace the address there with the one you are using. If you only want to listen to unicast servers, leave the line out.
### Linux (systemd)
@@ -83,6 +99,7 @@ After=network.target
ExecStart=/usr/bin/node /path/to/relay.js
Environment=OPENHAMCLOCK_URL=https://openhamclock.com
Environment=RELAY_KEY=your-secret-key
+Environment=MULTICAST=224.0.0.1 # If you want the relay to listen to multicast
Restart=always
RestartSec=5
User=your-username
@@ -103,6 +120,7 @@ Create a batch file `start-relay.bat`:
@echo off
set OPENHAMCLOCK_URL=https://openhamclock.com
set RELAY_KEY=your-secret-key
+set MULTICAST=224.0.0.1 # If you want the relay to listen to multicast
node C:\path\to\relay.js
```
@@ -110,10 +128,8 @@ Add it to Task Scheduler to run at login.
## Troubleshooting
-**Port already in use**: Another program is listening on 2237. Use `--port 2238` and update WSJT-X to match.
-
-**Authentication failed**: Double-check that `WSJTX_RELAY_KEY` in your server .env matches the `--key` you're passing to the relay.
+**Port already in use**: Another program is listening on 2237. Use `--port 2238` and update WSJT-X to match, or configure to use multicast.
**Connection errors**: The relay automatically retries with backoff. Check that your server URL is correct and accessible.
-**No decodes showing**: Make sure WSJT-X is set to UDP address `127.0.0.1` port `2237`, and that the "Accept UDP requests" checkbox is enabled.
+**No decodes showing**: Make sure WSJT-X is set to UDP address `127.0.0.1` (or the multicast address thaht you specified) port `2237`, and that the "Accept UDP requests" checkbox is enabled.
diff --git a/wsjtx-relay/relay.js b/wsjtx-relay/relay.js
index 870ed9aa..95895363 100644
--- a/wsjtx-relay/relay.js
+++ b/wsjtx-relay/relay.js
@@ -11,10 +11,12 @@
* Zero dependencies — uses only Node.js built-in modules.
*
* Usage:
- * node relay.js --url https://openhamclock.com --key YOUR_RELAY_KEY
+ * node relay.js --url https://openhamclock.com --key YOUR_RELAY_KEY [--multicast address]
+ * where the multicast address is something like 224.0.0.1
*
* Or with environment variables:
* OPENHAMCLOCK_URL=https://openhamclock.com RELAY_KEY=abc123 node relay.js
+ * MULTICAST=224.0.0.1
*
* In WSJT-X: Settings → Reporting → UDP Server
* Address: 127.0.0.1 Port: 2237
@@ -33,6 +35,7 @@ function parseArgs() {
const args = process.argv.slice(2);
const config = {
url: process.env.OPENHAMCLOCK_URL || '',
+ maddr: process.env.MULTICAST || '',
key: process.env.RELAY_KEY || process.env.OPENHAMCLOCK_RELAY_KEY || '',
session: process.env.RELAY_SESSION || '',
port: parseInt(process.env.WSJTX_UDP_PORT || '2237'),
@@ -50,6 +53,10 @@ function parseArgs() {
case '-k':
config.key = args[++i];
break;
+ case '--multicast':
+ case '-m':
+ config.maddr = args[++i];
+ break;
case '--session':
case '-s':
config.session = args[++i];
@@ -77,6 +84,9 @@ a remote OpenHamClock server.
Options:
--url, -u OpenHamClock server URL (required)
--key, -k Relay authentication key (required)
+ --multicast, -m
+ Bind to the specified multicast address rather than
+ a non-multicast socket
--session, -s Browser session ID (required for per-user isolation)
--port, -p Local UDP port to listen on (default: 2237)
--interval, -i Batch send interval in ms (default: 2000)
@@ -86,6 +96,7 @@ Options:
Environment variables:
OPENHAMCLOCK_URL Same as --url
RELAY_KEY Same as --key
+ MULTICAST Same as --multicast
RELAY_SESSION Same as --session
WSJTX_UDP_PORT Same as --port
BATCH_INTERVAL Same as --interval
@@ -456,7 +467,7 @@ function scheduleBatch() {
// UDP LISTENER
// ============================================
-const socket = dgram.createSocket('udp4');
+const socket = dgram.createSocket({ type: 'udp4', reuseAddr: true });
socket.on('message', (buf, rinfo) => {
const msg = parseWSJTXMessage(buf);
@@ -504,6 +515,15 @@ socket.on('listening', () => {
console.log(' Waiting for WSJT-X packets...');
console.log('');
+ if (!!config.maddr) {
+ try {
+ socket.addMembership(config.maddr);
+ console.log(`[WSJT-X] Joined multicast group ${config.maddr}`);
+ } catch (e) {
+ console.error(`[WSJT-X] Failed to join multicast group ${config.maddr}: ${e.message}`);
+ }
+ }
+
// Start batch relay loop
scheduleBatch();
@@ -623,8 +643,26 @@ socket.on('listening', () => {
}, 60000); // every minute
});
-// Bind to all interfaces so WSJT-X can reach it from any address
-socket.bind(config.port, '0.0.0.0');
+if (!!config.maddr) {
+ // Bind to 0.0.0.0 explicitly — on some Linux systems (especially Pi) omitting
+ // the address can cause the socket to bind to the wrong interface, preventing
+ // multicast group membership from working.
+ socket.bind(
+ {
+ port: config.port,
+ address: '0.0.0.0',
+ exclusive: false,
+ },
+ () => {
+ socket.setMulticastLoopback(true);
+ },
+ );
+} else {
+ socket.bind({
+ port: config.port,
+ address: '0.0.0.0',
+ });
+}
// ============================================
// GRACEFUL SHUTDOWN