热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在接收POST数据之前阻止Heroku上已部署的NodeJSWeb应用退出?

我对基于服务器的应用程序非常缺乏经验(而对客户端应用程序的经验只有一点

我对基于服务器的应用程序非常缺乏经验(而对客户端应用程序的经验只有一点点)。但是,基于许多示例(主要是在Stack Overflow上),我创建了一个基本的NodeJS Web应用程序,该应用程序在本地运行(例如“ heroku本地网络”)时可以正常运行。但是在部署后,除非我插入延迟,否则该应用程序不会接收到POST数据。我确定自己做错了,所以我希望有人可以指出正确的处理方式。我将应用程序精简为基本问题,仍然使用下面的代码显示。

据我所知,简单的网页基本上将JSON数据发布到我的Web应用程序中。 Web应用程序确实收到POST消息。但是在Web应用程序可以收集正在传输的数据之前,Web应用程序似乎已退出。当应用在本地运行时,数据不会丢失(当我在Google Cloud上部署早期版本时,数据也不会丢失)。但是,当部署在Heroku(免费版)上时,损失确实会发生。

其他几种语言的经验让我感到困惑,为什么NodeJS应用程序在收到任何消息之前并不总是退出,因为该应用程序中没有代码来延迟退出(例如消息泵或等待退出信号) 。当它起作用时,我耸了耸肩,认为游戏中有一些魔术,我以后会学习。但实际上,我看到的失败对我来说更有意义。

无论如何,正是这种怀疑导致我增加了延迟(下面显示的行带有// ***的注释)。由此,我能够确定数据已经到位,但没有被延迟收集。

下面是主要代码文件。在这些记录下,有一些日志显示了添加延迟前后的本地和远程行为。

任何帮助表示赞赏。

index.html:













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");

添加延迟前本地:

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' }

在添加延迟之前部署:

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

添加延迟后的本地:

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',color: 'red' }
10:48:17 PM web.1 | POST end

在添加延迟后部署:

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',color: 'red' }
2019-12-18T04:52:01.073243+00:00 app[web.1]: POST end



以防以后有人遇到此问题,我对此没有任何反馈,也无法真正找到合理的解决方法。 (我尝试了Promise和其他一些临时信号。)因此,我知道使用Express作为我的服务器,从而在全球范围内成功部署了这一点。考虑到极其简单的数据传输,切换是微不足道的,并且工作正常。 (我打算深入研究Express源,以了解他们如何处理它,但似乎将它包含在我的NodeJS应用程序中会导入200多个其他软件包,因此,实在是不鼓励使用。)


推荐阅读
  • 本文深入解析了 Apache 配置文件 `httpd.conf` 和 `.htaccess` 的优化方法,探讨了如何通过合理配置提升服务器性能和安全性。文章详细介绍了这两个文件的关键参数及其作用,并提供了实际应用中的最佳实践,帮助读者更好地理解和运用 Apache 配置。 ... [详细]
  • 在《PHP应用性能优化实战指南:从理论到实践的全面解析》一文中,作者分享了一次实际的PHP应用优化经验。文章回顾了先前进行的一次优化项目,指出即使系统运行时间较长后出现的各种问题和性能瓶颈,通过采用一些通用的优化策略仍然能够有效解决。文中不仅详细阐述了优化的具体步骤和方法,还结合实例分析了优化前后的性能对比,为读者提供了宝贵的参考和借鉴。 ... [详细]
  • 微信支付授权目录配置详解及操作步骤
    在使用微信支付时,若通过WeixinJSBridge.invoke方法调用支付功能,可能会遇到“当前页面URL未注册”的错误提示,导致get_brand_wcpay_request:fail调用微信JSAPI支付失败。为解决这一问题,需要正确配置微信支付授权目录,确保支付页面的URL已成功注册。本文将详细介绍微信支付授权目录的配置步骤和注意事项,帮助开发者顺利完成支付功能的集成与调试。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • Ceph API微服务实现RBD块设备的高效创建与安全删除
    本文旨在实现Ceph块存储中RBD块设备的高效创建与安全删除功能。开发环境为CentOS 7,使用 IntelliJ IDEA 进行开发。首先介绍了 librbd 的基本概念及其在 Ceph 中的作用,随后详细描述了项目 Gradle 配置的优化过程,确保了开发环境的稳定性和兼容性。通过这一系列步骤,我们成功实现了 RBD 块设备的快速创建与安全删除,提升了系统的整体性能和可靠性。 ... [详细]
  • 本文深入探讨了数据库性能优化与管理策略,通过实例分析和理论研究,详细阐述了如何有效提升数据库系统的响应速度和处理能力。文章首先介绍了数据库性能优化的基本原则和常用技术,包括索引优化、查询优化和存储管理等。接着,结合实际应用场景,讨论了如何利用容器化技术(如Docker)来部署和管理数据库,以提高系统的可扩展性和稳定性。最后,文章还提供了具体的配置示例和最佳实践,帮助读者在实际工作中更好地应用这些策略。 ... [详细]
  • 本课程详细介绍了如何使用Python Flask框架从零开始构建鱼书应用,涵盖高级编程技巧和实战项目。通过视频教学,学员将学习到Flask的高效用法,包括数据库事务处理和书籍交易模型的实现。特别感谢AI资源网提供的课程下载支持。 ... [详细]
  • 如何在Java中高效构建WebService
    本文介绍了如何利用XFire框架在Java中高效构建WebService。XFire是一个轻量级、高性能的Java SOAP框架,能够简化WebService的开发流程。通过结合MyEclipse集成开发环境,开发者可以更便捷地进行项目配置和代码编写,从而提高开发效率。此外,文章还详细探讨了XFire的关键特性和最佳实践,为读者提供了实用的参考。 ... [详细]
  • 题目描述:小K不幸被LL邪教洗脑,洗脑程度之深使他决定彻底脱离这个邪教。在最终离开前,他计划再进行一次亚瑟王游戏。作为最后一战,他希望这次游戏能够尽善尽美。众所周知,亚瑟王游戏的结果很大程度上取决于运气,但通过合理的策略和算法优化,可以提高获胜的概率。本文将详细解析洛谷P3239 [HNOI2015] 亚瑟王问题,并提供具体的算法实现方法,帮助读者更好地理解和应用相关技术。 ... [详细]
  • 如何构建基于Spring MVC框架的Java Web应用项目
    在构建基于Spring MVC框架的Java Web应用项目时,首先应创建一个新的动态Web项目。接着,需将必要的JAR包导入至WebContent/WEB-INF/lib目录下,确保包括Spring核心库及相关依赖。如遇缺失的JAR包,可向社区求助或通过Maven等工具自动下载。正确配置后,即可开始搭建应用结构与功能模块。 ... [详细]
  • 本文深入探讨了 HTML 中的 `margin` 属性,详细解析了其基本特性和应用场景。文章不仅介绍了 `margin` 的基本概念,还重点讨论了垂直外边距合并现象,并分析了 `margin` 在块级元素与内联元素中的不同表现。通过实例和代码示例,帮助读者全面理解 `margin` 的使用技巧和常见问题。 ... [详细]
  • 全新发布的自我修复与自我更新的Linux版本,专为云计算环境设计! ... [详细]
  • MVVM架构~mvc,mvp,mvvm大话开篇
    返回目录百度百科的定义:MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方:ControllerPresenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模 ... [详细]
  • 如何在Android应用中设计和实现专业的启动欢迎界面(Splash Screen)
    在Android应用开发中,设计与实现一个专业的启动欢迎界面(Splash Screen)至关重要。尽管Android设计指南对使用Splash Screen的态度存在争议,但一个精心设计的启动界面不仅能提升用户体验,还能增强品牌识别度。本文将探讨如何在遵循最佳实践的同时,通过技术手段实现既美观又高效的启动欢迎界面,包括加载动画、过渡效果以及性能优化等方面。 ... [详细]
  • 本文探讨了在Lumen框架中实现自定义表单验证功能的方法与挑战。Lumen的表单验证机制默认返回无状态的JSON格式API响应,这给初学者带来了一定的难度。通过深入研究Validate类,作者分享了如何有效配置和使用自定义验证规则,以提升表单数据的准确性和安全性。 ... [详细]
author-avatar
老娘叫凌凌_523
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有