i had built a sse example with vue3 and node.js , and node.js server is behind a nginx. Here is the implementation.
vue3 code
eventSource = new EventSource('https://app.kuangcc.com/sse/events');
eventSource.onmessage = function(event) {
console.log('event.value ',event.data); // received all the data at once
};
eventSource.onopen = function(event) {
console.log("EventSource connection opened"); // fired immediately
};
eventSource.onerror = (error) => {
console.error('SSE error:', error); // received an error after all data received
eventSource.close();
}
node.js code
app.get("/sse/events", (req, res) => {
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Connection", "keep-alive");
res.setHeader("X-Accel-Buffering", "no");
res.flushHeaders();
res.write(
'event: message' + '\n' +
'data:' + 'message2' + '\n' +
'retry:' + '2000' + '\n' +
'id:' + '12345' + '\n\n'
)
let counter = 0;
let interval = setInterval(() => {
counter++;
if (counter > 10) {
clearInterval(interval);
res.end();
}
res.write(`id: interval${counter} \n`);
//res.write(`event: message \n`);
res.write(`data: ${JSON.stringify({ num: counter })}\n\n`);
}, 1000);
res.on("close", () => {
clearInterval(interval);
res.end();
});
});
nginx
location /sse {
proxy_pass http://localhost:3000;
tcp_nodelay on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400;
proxy_send_timeout 500;
keepalive_timeout 500;
# Other necessary SSE headers
proxy_set_header Cache-Control 'no-cache';
proxy_set_header Connection 'keep-alive';
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "Upgrade";
}
however the app runs, eventsource executes the open event immediately, but never stream data until return the whole message at once, at last it comes with an end error after all data received.
here is the chrome debugging view.
I tried to test with curl
curl -H Accept:text/event-stream https://app.kuangcc.com/sse/events
this works perfectly that the streaming is working well, so it looks like the server and nginx are all working well, and more likely the problem occurs in the frontend side.
anyone knows how to find out the problem & solution, I am so puzzled.
update
previously I only test it in the cloud, now I just try the node server and vue frontend in the local environment without considering the nginx, the issue still happens , obviously the issue is something between node.js server and vue client.
finally found out i need to disable compression, it prevents the ssr.
// app.use(compression());