I have a very simple set up.
NodeJs
export default class StreamController {
public static newMessage = async (req: Request, res: Response) => {
const { userid } = req.params;
res.writeHead(200, {
"Connection": "keep-alive",
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
});
setInterval(async () => {
console.log(await MessagesController.hasNewMessage(userid));
res.write(`${JSON.stringify({ hasUnread: await MessagesController.hasNewMessage(userid) })}`);
res.write("\n\n");
}, 5000);
}
}
React
constructor() {
super();
const uid = getUserId();
const eventSource = new EventSource(`http://localhost:8080/stream/messages/${uid}`)
eventSource.onmessage = (e) => {
console.log(e)
}
}
I can see that stream was opened but none event was passed from the server, while data was issued on the server side. What I'm doing wrong?
You are passing the data
on server side, but are not passing the event name as event
. This is how I solved the issue (simplified reproduction):
Server:
app.get('/stream', (req, res) => {
console.log('request received');
res.writeHead(200, {
"Connection": "keep-alive",
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
});
setInterval(async () => {
res.write('event: ping\n'); // added these
res.write(`data: ${JSON.stringify({ hasUnread: true })}`);
res.write("\n\n");
}, 5000);
});
Client:
constructor(props) {
super(props);
const eventSource = new EventSource(`http://localhost:3030/stream`);
eventSource.onopen = e => {
console.log(e);
}
eventSource.onmessage = e => {
console.log('onmessage');
console.log(e);
}
eventSource.addEventListener('ping', e => {
console.log(e);
});
}
The ping event will be firing every 5 seconds.
Now, if you want the eventSource.onmessage
to be called, you should name the event
as message on server side:
...
setInterval(async () => {
res.write('event: message\n'); // message event
res.write(`data: ${JSON.stringify({ hasUnread: true })}`);
res.write("\n\n");
}, 5000);
...
Now you will see in the console:
onmessage MessageEvent {..., data: "{'hasUnread': true}", ...}
Note that in this case the ping event won't be fired any more. More info here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With