Node.js/TypeScript backend that connects to a DXSpider Telnet node and republishes its events over WebSockets, with health-check endpoints, structured logging, and test coverage.
- Resilient Telnet client with exponential backoff reconnects, keep-alives, and basic prompt handling.
- DXSpider line parser producing structured JSON spot, announcement, WWV, and system events.
- WebSocket gateway (ws) with per-client filtering, subscriptions, and heartbeat management.
- Express HTTP API providing health and version endpoints.
- Structured logging via Pino.
- Jest unit tests for the parser and integration test for Telnet ➜ WebSocket flow using a mock Telnet driver.
- ESLint + Prettier for code quality and formatting.
- Dockerfile and optional docker-compose stack with a mock static frontend.
- Node.js 20+
- npm 9+
npm installCreate an .env file (optional) to override defaults:
TELNET_HOST=dxfun.com
TELNET_PORT=8000
TELNET_CALLSIGN=YOUR_CALLSIGN
TELNET_PASSWORD=optional_password
TELNET_INITIAL_COMMANDS=sh/wwv,sh/dx
TELNET_KEEPALIVE_COMMAND=\n
TELNET_KEEPALIVE_MS=120000
TELNET_FORCE_LOGIN=true
TELNET_FORCE_LOGIN_INTERVAL_MS=2000
TELNET_FORCE_LOGIN_MAX_ATTEMPTS=5
TELNET_FORCE_LOGIN_PASSWORD_DELAY_MS=800
ALLOWED_ORIGINS=http://localhost:3000,http://localhost,http://127.0.0.1,http://192.168.86.43,http://83.41.64.82
ALLOWED_IPS=127.0.0.1,192.168.86.43,83.41.64.82
LOG_LEVEL=info
HTTP_PORT=3000
WEBSOCKET_PATH=/ws# Run in watch mode with automatic restart
npm run dev
# Type-check and build
npm run build
# Start compiled output
npm startnpm run lint
npm testTests mock the Telnet layer; no external connectivity is required.
Build and run the service locally:
docker build -t dxspider-backend .
docker run --rm -p 3000:3000 dxspider-backendOr launch the backend together with the mock frontend:
docker-compose up --buildVisit http://localhost:8080 to load the mock frontend and inspect WebSocket traffic in the browser console.
- Telnet connection retries with exponential backoff (
TELNET_RECONNECT_BASE_MS,TELNET_RECONNECT_MAX_MS). - Keep-alive commands (blank line by default) are sent at
TELNET_KEEPALIVE_MSinterval. - Forced login (opt-in) can resend your callsign/password automatically; configure via
TELNET_FORCE_LOGINand related settings. - HTTP layer protected with Helmet and IP allow-list; CORS allow-list plus matching WebSocket origin/IP guard enforced via
ALLOWED_ORIGINSandALLOWED_IPS. - WebSocket clients can set filters via query parameters (
?bands=20m,40m&modes=FT8&text=CQ) or by sending{ "type": "subscribe", "filter": { ... } }messages. - Heartbeats (
ping/pong) ensure stale WebSocket clients are closed automatically.
- Confirm with the cluster administrator which login sequence is required (callsign, password, initial commands) and set the corresponding environment variables.
- Adjust
TELNET_INITIAL_COMMANDSfor the node (e.g.,set/spot/add,set/band) to fine-tune the stream delivered by DXSpider. - Review spot parsing rules in
src/parsers/dxSpiderParser.tsif your cluster emits custom formats; extend the parser and update unit tests accordingly. - Harden deployment settings: configure
LOG_LEVEL, ensure the process runs under a supervisor (systemd, pm2, Kubernetes), and place the service behind TLS termination if exposed publicly. - Monitor connection metrics via external tooling (e.g., Prometheus sidecar) to catch connectivity issues.
src/
app.ts # Composition root wiring Telnet, HTTP, WebSocket
config.ts # Environment configuration loader
drivers/telnetClient.ts
http/server.ts # Express HTTP server
parsers/dxSpiderParser.ts
services/dxSpiderService.ts, filtering.ts
websocket/server.ts
utils/* # Shared helpers (backoff, line buffering)
tests/
parser/ # Unit tests for parser
integration/ # Telnet ➜ WebSocket integration tests
Logs follow Pino JSON format by default. Pipe through pino-pretty in development:
npm install --save-dev pino-pretty
node dist/index.js | npx pino-prettyContributions and extensions (e.g., REST subscriptions, persistence) can build on the modular services and parsers provided here.