I have a Next.js (React) client that I've setup to listen to Server-Sent Events from my Node.js/Express.js server, but it doesn't seem to be receiving messages for some reason.
The open
and error
events of EventSource
are working properly, but whenever I use .onmessage
it doesn't detect anything.
What am I doing wrong?
Express.js Code:
router.get('/stream/:walletAddress', async (req, res, next) => {
try {
res.set({
Connection: 'keep-alive',
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Access-Control-Allow-Origin': '*'
});
res.flushHeaders();
let x = 0;
const id = setInterval(() => {
res.write(`event: message\n`);
res.write(`data: ${x++}\n\n`);
}, 2000);
res.on('close', () => {
console.log('Client closed.');
clearInterval(id);
});
} catch (err) {
next(err);
}
});
Next.js (React) Code:
import { API_URL } from 'config';
import { useWalletStore } from 'src/stores';
export const FetchTxsProvider = ({ children }) => {
const safeSdkReader = useWalletStore(state => state.safeSdkReader);
useEffect(() => {
const eventSource = new EventSource(
`${API_URL}/transactions/stream/${safeSdkReader.getAddress()}`
);
eventSource.onopen = function (e) {
console.log('Successfully connected.');
};
eventSource.onerror = function (err) {
console.error(err);
eventSource.close();
};
// ! Should fire here but doesn't!
eventSource.onmessage = function (event) {
console.log('Event: ', event);
};
return () => {
console.log('Connection closed.');
eventSource.close();
};
}, [safeSdkReader]);
return <>{children}</>
};
Don't know why, but the headers were missing 'Content-Encoding': 'none'
.
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Content-Encoding': 'none',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*'
});