Am using server sent events in an express server like this;
const sendEventDashboard = async (req, res) => {
try {
const orders = await Order.find({ agent_id: req.params.id })
.populate("agent_id")
.sort({ _id: -1 });
res.writeHead(200, {
"Cache-Control": "no-cache",
"Content-Type": "text/event-stream",
Connection: "keep-alive",
});
const sseId = new Date().toDateString();
const intervalId = setInterval(() => {
writeEvent(res, sseId, JSON.stringify(orders));
}, SEND_INTERVAL);
res.on("close", () => {
clearInterval(intervalId);
res.end();
// console.log("Client closed connection browser");
});
} catch (error) {
console.log(error);
}
};
export const getOrdersStreamDashboard = async (req, res) => {
if (req.headers.accept === "text/event-stream") {
sendEventDashboard(req, res);
} else {
res.json({ message: "Okay" });
}
};
and this is how i use it in a react app using a useEffect hook;
useEffect(() => {
const es = new EventSource(
`${process.env.REACT_APP_SERVER_URL}/weborders/${agentId}/stream_dashboard`
);
es.addEventListener("open", () => {
console.log("Dashboard stream opened!");
});
es.addEventListener("message", (e) => {
const data = JSON.parse(e.data);
setTrackOrderCount(data);
});
return () => {
// es.removeAllEventListeners();
es.close();
es.removeEventListener("message", (e) => {
const data = JSON.parse(e.data);
setTrackOrderCount(data);
});
};
}, [trackOrderCount]);
Everything runs as desired apart from event source always running until when the app/browser crushes. I get no error when it stops running and have to refresh for it to start again. This happens like after 10mins of inactivity or being on that same page for a long duration. Is there a way I can only run sse only when the state in the server is different from that of the client because i think the browser crushes because server sent events continuously run even when there's no event. I tried to remove the dependency array [trackOrderCount] in the useEffect and the setInterval in the server but that didn't solve the issue.
The solution might be in comparing the local and global versions before the event is sent but i've failed to figure out where to put that logic! I the browser's console, this is what i get;
and this will run for sometime then crush!