Amon
Amon

Reputation: 2971

ExpressJS server doesnt keep connection open for SSE

I am trying to implement SSE for a notifications feature, when the user first connects to the stream the backend is supposed to write their current notifications to it, which seems to be working. However it immediately closes the connection instead of keeping it open so I can write new notifications to it in the future:

backend notifications handler:

var clientStreams = []; // this is a list of all the streams opened by pract users to the backend
var newNotifications = [];
// every time a practitioner connects this event handler is run
// and a new stream is created for the newly connected practitioner

async function notificationEventsHandler(req, res) {
  const headers = {
    "Content-Type": "text/event-stream",
    Connection: "keep-alive",
    "Cache-Control": "no-cache",
  };

  const clientEmail = req.headers.patientemail;

  const data = await ApptNotificationData.findAll({
    where: {
      patientEmail: clientEmail,
      accepted: "1",
    },
  });

  res.writeHead(200, headers);
  res.write(`data:${JSON.stringify(data)}\n\n`);

  const newClientStream = {
    clientEmail: clientEmail,
    res,
  };

  // add the new stream to list of streams
  clientStreams.push(newClientStream);
  //console.log("PRACT STREAMS", clientStreams)

  req.on("close", () => {
    console.log(`${clientEmail} Connection closed`);
    clientStreams = clientStreams.filter(
      (client) => client.clientEmail !== client.clientEmail
    );
    
  });

  
}

frontend:

useEffect(() => {
    const fetchData = async () => {
    await fetchEventSource("https://api.***.com/client_notifications", {
        method: "GET",
        headers: {
          Accept: "text/event-stream",
          patientemail: patientData.email
        },
        onopen(res) {
          if (res.ok && res.status === 200) {
            console.log("Connection made ", res);          
          } else if (
            res.status >= 400 &&
            res.status < 500 &&
            res.status !== 429
          ) {
            console.log("Client side error ", res);
          }
        },
        onmessage(event) {
          const data = JSON.parse(event.data)
        },
        onclose() {
          console.log("Connection closed by the server");
        },
        onerror(err) {
          console.log("There was an error from server", err);
        },
      })
    }
    fetchData();
  }, [])

nginx conf:

server {
        
    listen 80;
    listen [::]:80;

    server_name api.***.com;

    location /client_notifications {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_pass http://nodejs:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "";
            chunked_transfer_encoding off;
            proxy_buffering off;
            proxy_cache off;


            if ($request_method = 'OPTIONS') {
                    add_header 'Access-Control-Allow-Origin' '*';
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,practemail,patientEmail';
                    add_header 'Access-Control-Max-Age' 1728000;
                    add_header 'Content-Type' 'text/plain; charset=utf-8';
                    add_header 'Content-Length' 0;
                    return 204;
            }
            if ($request_method = 'POST') {
                    add_header 'Access-Control-Allow-Origin' '*' always;
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
                    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,practemail,patientEmail' always;
                    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
            }
            if ($request_method = 'GET') {
                    add_header 'Access-Control-Allow-Origin' '*' always;
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
                    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,practemail,patientEmail' always;
                    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
            }
    }
}


server {
listen 443 ssl;

server_name api.**.com www.api.**.com;
ssl_certificate     /etc/ssl/-.crt;
ssl_certificate_key /etc/ssl/-.key;


    location /client_notifications {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_pass http://nodejs:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "";
            chunked_transfer_encoding off;
            proxy_buffering off;
            proxy_cache off;
            
    }
}

How do I keep the connection open? Thank you in advance

Upvotes: 0

Views: 29

Answers (0)

Related Questions