¿Cómo evito que una aplicación web NodeJS implementada en Heroku salga antes de recibir datos POST?

artillería

No tengo mucha experiencia en aplicaciones basadas en servidor (y solo un poco más en aplicaciones del lado del cliente). Sin embargo, en base a una serie de ejemplos (principalmente aquí en Stack Overflow), he creado una aplicación web básica de NodeJS, que funciona correctamente cuando se ejecuta localmente (por ejemplo, "heroku local web"). Pero cuando se implementa, la aplicación no recibe datos POST, a menos que inserte un retraso. Estoy seguro de que estoy haciendo algo mal, así que espero que alguien me pueda indicar la forma correcta de manejar esto. He resumido la aplicación hasta el problema básico, que todavía aparece con el código a continuación.

Básicamente, según tengo entendido, la página web simple publica datos JSON en mi aplicación web. La aplicación web recibe el mensaje POST. Pero antes de que la aplicación web pueda recopilar los datos que se transfieren, la aplicación web parece cerrarse. Los datos no se pierden cuando la aplicación se ejecuta localmente (y no se pierden cuando implementé una versión anterior en Google Cloud). Pero la pérdida ocurre cuando se implementa en Heroku (nivel gratuito).

La experiencia en varios otros idiomas me deja confundido sobre por qué la aplicación NodeJS no siempre se cierra antes de recibir cualquier mensaje, ya que no hay ningún código en la aplicación para retrasar la salida (por ejemplo, una bomba de mensajes o esperar una señal de salida). Cuando funcionó, me encogí de hombros y decidí que había algo de magia en juego que aprendería más tarde. Pero en realidad, el fracaso que estoy viendo tiene más sentido para mí.

En cualquier caso, fue esta duda la que me llevó a agregar el retraso (líneas agregadas que se muestran a continuación con comentarios de // ***). A partir de eso, pude determinar que los datos llegaban, pero no se recopilaban, sin demora.

A continuación se muestran los archivos de código principales. Debajo hay algunos registros que muestran el comportamiento local y remoto antes y después de que se agregó el retraso.

Cualquier ayuda apreciada.

index.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang='en'>
<meta http-equiv='Content-Language' content='en'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>

<script>

var scriptlocation = location.href.replace(document.location.pathname, '');
var request = new XMLHttpRequest();

function OnReadyStateChange() {
  if (request.readyState == 4 && request.status == 200) {
    console.log("Data upload complete.");
  }
}

function SendDataToServer(data) {
  var url = scriptlocation + "/server.js";
  request.open('POST', url, true);
  request.setRequestHeader('Content-type', 'application/json');
  request.onreadystatechange = OnReadyStateChange;
  request.send(data);
}

function SendEntryDataToServer() {
  var entryData = {
    fruit: "apple",
    size: "medium",
    color: "red"
  };
  console.log("*** SENDING DATA TO SERVER ***");
  var postData = JSON.stringify(entryData);
  SendDataToServer(postData);
  return false;
}

</script>
</head>
<body>
  <form>
    <input type="button" onclick="SendEntryDataToServer()" value="Post Data"/>
  </form>
</body>

server.js:

const http = require('http');
const fs = require('fs');

var server = http.createServer(
  function (req, res) {
    console.log(`req.url: ${req.url}\n`);

    if (req.method == 'POST') {
      console.log("POST");

      var body = '';

      req.on('data', function (data) {
        body += data;
      });

      req.on('end', function (data) {
        console.log(JSON.parse(body));
      });

      res.writeHead(200, {'Content-Type': 'text/html'});
      res.end('post received');

      console.log("Sleeping 5 seconds"); // ***
      setTimeout(function(){             // ***
        console.log("POST end");
      }, 5000);                          // ***
    } else {
      console.log("GET");

      fs.readFile('./' + req.url, function(err, data) {
        if (!err) {
          var dotoffset = req.url.lastIndexOf('.');
          var mimetype = dotoffset == -1
                        ? 'text/plain'
                        : {
                          '.html' : 'text/html',
                          '.ico' : 'image/x-icon',
                          '.jpg' : 'image/jpeg',
                          '.png' : 'image/png',
                          '.gif' : 'image/gif',
                          '.css' : 'text/css',
                          '.js' : 'text/javascript'
                        }[ req.url.substr(dotoffset) ];
          res.setHeader('Content-type' , mimetype);
          res.end(data);
        } else {
          console.log ('file not found: ' + req.url);
          res.writeHead(404, "Not Found");
          res.end();
        }
      });
    }
  }
);

const PORT = process.env.PORT || 5000;
server.listen(PORT, () => {
  console.log(`Server is running (port: ${PORT})...`);
});

console.log("FILE end");

Local antes de la demora agregada:

10:24:00 PM web.1 |  FILE end
10:24:00 PM web.1 |  Server is running (port: 5000)...
10:24:14 PM web.1 |  req.url: /index.html
10:24:14 PM web.1 |  GET
10:24:18 PM web.1 |  req.url: /server.js
10:24:18 PM web.1 |  POST
10:24:18 PM web.1 |  POST end
10:24:18 PM web.1 |  { fruit: 'apple', size: 'medium', color: 'red' }

Implementado antes de que se agregue el retraso:

2019-12-18T04:31:52.835329+00:00 app[web.1]: FILE end
2019-12-18T04:31:52.837439+00:00 app[web.1]: Server is running (port: 17378)...
2019-12-18T04:32:14.929250+00:00 heroku[router]: at=info method=GET path="/index.html" host=****.herokuapp.com request_id=**** fwd="*.*.*.*" dyno=web.1 connect=0ms service=9ms status=200 bytes=1233 protocol=https
2019-12-18T04:32:14.925381+00:00 app[web.1]: req.url: /index.html
2019-12-18T04:32:14.925407+00:00 app[web.1]:
2019-12-18T04:32:14.925509+00:00 app[web.1]: GET
2019-12-18T04:32:25.004774+00:00 app[web.1]: req.url: /server.js
2019-12-18T04:32:25.004809+00:00 app[web.1]:
2019-12-18T04:32:25.004964+00:00 app[web.1]: POST
2019-12-18T04:32:25.006023+00:00 app[web.1]: POST end

Local después del retraso agregado:

10:48:04 PM web.1 |  FILE end
10:48:04 PM web.1 |  Server is running (port: 5000)...
10:48:08 PM web.1 |  req.url: /index.html
10:48:08 PM web.1 |  GET
10:48:12 PM web.1 |  req.url: /server.js
10:48:12 PM web.1 |  POST
10:48:12 PM web.1 |  Sleeping 5 seconds
10:48:12 PM web.1 |  { fruit: 'apple', size: 'medium', color: 'red' }
10:48:17 PM web.1 |  POST end

Implementado después de la demora agregada:

2019-12-18T04:51:50.925802+00:00 app[web.1]: req.url: /index.html
2019-12-18T04:51:50.925831+00:00 app[web.1]:
2019-12-18T04:51:50.925944+00:00 app[web.1]: GET
2019-12-18T04:51:56.071684+00:00 heroku[router]: at=info method=POST path="/server.js" host=****.herokuapp.com request_id=**** fwd="*.*.*.*" dyno=web.1 connect=0ms service=6ms status=200 bytes=151 protocol=https
2019-12-18T04:51:56.064644+00:00 app[web.1]: req.url: /server.js
2019-12-18T04:51:56.064659+00:00 app[web.1]:
2019-12-18T04:51:56.068033+00:00 app[web.1]: POST
2019-12-18T04:51:56.069013+00:00 app[web.1]: Sleeping 5 seconds
2019-12-18T04:51:56.075197+00:00 app[web.1]: { fruit: 'apple', size: 'medium', color: 'red' }
2019-12-18T04:52:01.073243+00:00 app[web.1]: POST end
artillería

En caso de que alguien se encuentre con esto más tarde, no recibí ningún comentario sobre esto y realmente no pude encontrar una solución razonable. (Probé promesas y alguna otra señalización ad-hoc.) Así que lo esquivé al usar Express como mi servidor, sabiendo que esto se implementa con éxito en todo el mundo. El cambio fue trivial, dada la transferencia de datos extremadamente simple, y funciona bien. (Tenía la intención de profundizar en la fuente Express para ver cómo lo manejaban, pero parece que incluirlo en mi aplicación NodeJS importó algo más de 200 paquetes más, por lo que fue un gran desánimo investigar).

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

CalienteEtiquetas

Archivo