Skip to main content

Chat Server (chat-server.js)

A zero-dep Node companion service on the production box that gives the static PWA a live chat + listener presence without WebSockets or npm — plain HTTP long-poll REST, which also avoids mixed-content on the HTTP static page.

  • Where: /home/sms/radio/chat-server.js (remote, user sms)
  • Port: 8094
  • Public base: http://files.mediahubnetwork.net:8094

Endpoints

MethodPathBodyReturns
GET/api/healthliveness
POST/api/chat/join{name}{token,name,color,emoji,heartbeatMs:30000,history}
POST/api/chat/messages{token,text}message object (500-char max, 1.2s rate limit)
GET/api/chat/history?since=&limit=message history
GET/api/chat/presenceonline users
POST/api/chat/heartbeat{token}extends the 75s session TTL

History: 800 messages persisted to /home/sms/radio/chat_data/history.jsonl.

Engine proxy (observability for the static page)

The same server also proxies the Windows control plane so the browser only ever talks to one origin:

  • GET /api/next → engine /next-tracks.json
  • GET /api/status → engine /api/status
  • GET /api/station/state → engine /api/station/state
  • GET /api/content/status → engine /api/content/status
  • POST /api/push/register → engine /api/subscribe

Upstream: http://10.40.3.174:5000.

Daemon + restart

  • Watchdog: watch_chat.sh (foreground while-loop restart), launched via cron @reboot sleep 40 && setsid nohup /home/sms/radio/watch_chat.sh (matches the start-player.sh pattern; no per-minute cron needed).
  • Clean restart: bash restart_chat.sh (fuser -k 8094/tcp + rm -f history.jsonl). Never pkill -f — it kills the SSH invocation itself.

Client wiring

html/index.html holds the CHAT_URL const; the #view-chat view is wired to the nav + bottom-nav Chat buttons. See PWA for the presence UI details.

  • PWA — the client that consumes chat + presence.
  • Live stack — the rest of the production node.