I am converting an existing production application from jquery to react.js. The backend is written in Java (spring boot). The existing app uses Server-Sent Events to push certain types of notifications from the server backend to the web clients. The existing production app works fine.
For the UI rewrite, I'm using react.js made with CRA (Create React App) port 3000 and default proxy through to my spring boot server on the same machine running on port 7001 all in development environment.
From React, the EventSource is getting instantiated and the request is passing through over to the spring boot server. It is registering the user and everything looks OK. When a notification message is to be sent from springboot to react I see the onopen() message handler called in React and the readyState transitions from 0 (pending) to 1 (open). And then nothing happens. on-message handler is never called. There are no errors in the javascript console, or on the springboot server backend (even with DEBUG level enabled for all packages). I don't see any errors in the browser Network tab (Firefox in this case). In another browser I have one of the old jquery clients running and it does get the message.
"proxy": "https://localhost:7001",
"private": true,
"dependencies": {
"@ant-design/icons": "^5.0.1",
"@reduxjs/toolkit": "^1.9.4",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"antd": "^5.4.2",
"antd-mobile": "^5.29.1",
"antd-mobile-icons": "^0.3.0",
"axios": "^1.3.5",
"bounce.js": "^0.8.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"web-vitals": "^3.3.1"
},
Code snippet from react functional component:
const eventSource = new EventSource("/api/register/39/event/944?registrationCode=MDB");
console.log(`DEBUG: eventSource.readyState=${eventSource.readyState}`);
useEffect(() => {
console.log(`DEBUG: useEffect| eventSource.readyState=${eventSource.readyState}`);
eventSource.onopen = (e) => {
console.log("DEBUG: eventSource connection open!",e);
console.log(`DEBUG: onopen | eventSource.readyState=${eventSource.readyState}`);
};
eventSource.onerror = (e) => {
if (e.readyState === EventSource.CLOSED) {
console.log("DEBUG: eventSource connection CLOSED! Trying to reconnect!");
}
};
eventSource.onmessage = (event) => {
console.log("DEBUG: onmessage received! result=",event.data);
};
// return function cleanup() {
// console.log(
// `DEBUG: EventSourceController.cleanup() called. Closing open stream.`
// );
// eventSource.close();
// };
//[eventSource]
});
I've searched the web to see if there is any funny business to be looking for when it comes to SSE and React, but nothing jumps out.
There is this similar unanswered question here but I don't have enough reputation points to up-vote it or even provide a comment.
I have no reason to believe that the message-type is being overwritten on the backend as this post suggests, as I am using the same message handler in the old jquery app and it is able to receive the messages without any issue.