我在Azure托管的Nodejs上有一个Web应用程序。其中一个表单启动一个非常长、占用CPU的计算,可能需要几分钟时间。天真的标准实现最终超时,在4分钟的默认Azure值之后出现错误500。
为了避免这种情况,我基于http://hungtran.co/long-polling-and-websockets-on-nodejs/
在客户端,我有一个AJAX调用,超时为0,无限:
$("#optimBtn").click(function() {
subscribe(onMessage);
var form = document.theForm;
form.setAttribute("method", "post");
form.setAttribute("action", "/legs/optim");
form.submit();
})
function subscribe(callback) {
var longPoll = function() {
$.ajax({
method: 'GET',
url: '/legs/messages',
dataType: 'json',
success: function(data) { callback(data) },
complete: function() {},
timeout: 0 // (is ms) none
})
}
longPoll()
}
服务器端使用EventEmitter向客户端发布包含计算结果的消息:
var EventEmitter = require('events').EventEmitter
var messageBus = new EventEmitter()
messageBus.setMaxListeners(100)
router.get('/messages', function(req, res) {
var addMessageListener = function(res) {
messageBus.once('message', function(data) {
res.json(data)
})
}
addMessageListener(res)
})
计算部分被设计为在SuperLongAsync((工作时不保存请求:
var optim_post = async function(req, res, next) {
somethingSuperLongAsync().then(results => {
messageBus.emit('message', results)
})
res.status(200).end()
};
router.post('/optim', optim_post);
它适用于短作业:当单击optimBtn时,客户端在/slegs/messages上订阅服务器,将表单发布到/optim上,并在完成后接收结果。然而,当进程耗时超过4分钟时,ajax调用仍然返回500/超时。
如何分叉长进程,使其可以绕过超时?
感谢
回复我自己:问题解决了切换到WebSockets而不是使用Ajax 进行长轮询