MQTT messages received in Node.js container but not delivered to browser via SSE (Docker on Raspberry Pi 5)

Problem MQTT messages are successfully published to the broker and received by my Node.js container (confirmed in logs), but they are never delivered to the browser through Server-Sent Events (SSE). The browser’s EventSource stays connected, yet no events arrive and the UI never updates.

Expected behavior When I run mosquitto_pub -t “openclaw/alert” -m “test message”, the message should appear immediately in the browser UI.

Actual behavior The message reaches the Node.js container (log appears), but nothing is pushed to the browser. Old data remains displayed forever.

Environment

Server-side code (web-dashboard.js)

JavaScript

const express = require('express');
const mqttHandler = require('./mqtt-handler.js');

const app = express();
let sseClients = [];

// SSE endpoint
app.get('/events', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  res.write('data: {"type":"connected"}\n\n');

  sseClients.push(res);

  const keepAlive = setInterval(() => {
    res.write(': keep-alive\n\n');
  }, 15000);

  req.on('close', () => {
    clearInterval(keepAlive);
    sseClients = sseClients.filter(c => c !== res);
  });
});

// MQTT → SSE bridge
mqttHandler.client.on('message', (topic, message) => {
  console.log(`📨 MQTT received: ${topic} → ${message.toString()}`);
  if (topic === 'openclaw/alert') {
    const payload = JSON.stringify({ type: 'alert', message: message.toString() });
    sseClients.forEach(client => {
      client.write(`data: ${payload}\n\n`);
    });
  }
});

app.listen(3000, '0.0.0.0', () => {
  console.log("🌐 Dashboard connected to MQTT bus with real-time SSE");
});

Client-side code (browser)

JavaScript

const evtSource = new EventSource('/events');
evtSource.onmessage = function(event) {
  const data = JSON.parse(event.data);
  if (data.type === 'alert') {
    const el = document.getElementById('liveEvents');
    el.innerHTML += '
' + data.message; el.scrollTop = el.scrollHeight; } };

Logs from docker logs openclaw-web-dashboard

text

🌐 Dashboard connected to MQTT bus with real-time SSE
📨 MQTT received: openclaw/alert → 🧪 TEST ALERT - Broker is now running in Docker

The log appears every time I publish a message, but the browser never receives it.

What I’ve tried

Any idea why the SSE clients are not receiving the events even though the server processes the MQTT message?

Read more here: Source link

MQTT messages received in Node.js container but not delivered to browser via SSE (Docker on Raspberry Pi 5)

Problem MQTT messages are successfully published to the broker and received by my Node.js container (confirmed in logs), but they are never delivered to the browser through Server-Sent Events (SSE). The browser’s EventSource stays connected, yet no events arrive and the UI never updates.

Expected behavior When I run mosquitto_pub -t “openclaw/alert” -m “test message”, the message should appear immediately in the browser UI.

Actual behavior The message reaches the Node.js container (log appears), but nothing is pushed to the browser. Old data remains displayed forever.

Environment

Server-side code (web-dashboard.js)

JavaScript

const express = require('express');
const mqttHandler = require('./mqtt-handler.js');

const app = express();
let sseClients = [];

// SSE endpoint
app.get('/events', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  res.write('data: {"type":"connected"}\n\n');

  sseClients.push(res);

  const keepAlive = setInterval(() => {
    res.write(': keep-alive\n\n');
  }, 15000);

  req.on('close', () => {
    clearInterval(keepAlive);
    sseClients = sseClients.filter(c => c !== res);
  });
});

// MQTT → SSE bridge
mqttHandler.client.on('message', (topic, message) => {
  console.log(`📨 MQTT received: ${topic} → ${message.toString()}`);
  if (topic === 'openclaw/alert') {
    const payload = JSON.stringify({ type: 'alert', message: message.toString() });
    sseClients.forEach(client => {
      client.write(`data: ${payload}\n\n`);
    });
  }
});

app.listen(3000, '0.0.0.0', () => {
  console.log("🌐 Dashboard connected to MQTT bus with real-time SSE");
});

Client-side code (browser)

JavaScript

const evtSource = new EventSource('/events');
evtSource.onmessage = function(event) {
  const data = JSON.parse(event.data);
  if (data.type === 'alert') {
    const el = document.getElementById('liveEvents');
    el.innerHTML += '
' + data.message; el.scrollTop = el.scrollHeight; } };

Logs from docker logs openclaw-web-dashboard

text

🌐 Dashboard connected to MQTT bus with real-time SSE
📨 MQTT received: openclaw/alert → 🧪 TEST ALERT - Broker is now running in Docker

The log appears every time I publish a message, but the browser never receives it.

What I’ve tried

Any idea why the SSE clients are not receiving the events even though the server processes the MQTT message?

Read more here: Source link