当Node.js请求其他服务器的长时间http请求时,Node.js的正确行为是什么?
What is the correct behavior for Node.js while Node.js is requesting a long time http request for other servers
当Node.js请求长时间http请求时,Node.js的正确行为是什么?情况是,我的node.js服务器就像客户端和数据库层之间的web代理(由web服务暴露)。客户端将同时向Node.js发送多个请求,Node.js将使用request.js将请求传递给web服务。有些web服务需要几秒钟才能获得响应。因为响应的处理程序在request.js中使用回调方式,它应该被推入事件循环,node.js应该转移到新的请求,而不会等待响应。但是在我的应用程序中,node.js在得到之前的响应之前不会处理新的请求。我不确定哪一种是正确的行为。对于request.js,我添加了一个代理选项,以避免被默认套接字阻塞。var requestObj = {
url : targetUrl,
json : true,
pool: new http.Agent()
}
请帮我一下。如果node.js在得到响应之前不会处理请求,我看不出使用node.js的原因,所以我认为问题是由我的错误代码引起的。下面是发送http请求的类。
var request = require('request');
var http = require('http');
function apiService(){}
apiService.prototype.get = function (context, payload, callback, url){
return this.requestAPI(context, payload, callback, url, "GET");
}
apiService.prototype.post = function(context, payload, callback, url){
return this.requestAPI(context, payload, callback, url, "POST");
}
apiService.prototype.del = function(context, payload, callback, url){
return this.requestAPI(context, payload, callback, url, "DELETE");
}
apiService.prototype.requestAPI = function(context, payload, callback, url, method){
var config = context.config;
var targetUrl = config.APIHost
+ (config.port == null ? "": (":" + config.port))
+ "/"
+ config.baseDir
+ "/"
+ url;
var requestObj = {
url : targetUrl,
json : true,
pool: new http.Agent()
}
if (config.proxy != null){
requestObj.proxy = config.proxy;
}
switch (method){
case "POST":
requestObj.body = payload;
request.post(requestObj, function (err, resp, body){
if (err){
callback(err);
return;
}
callback(null, body);
});
break;
case "GET":
var queryString = "";
for (att in payload){
if (queryString != "")
queryString += "&";
queryString += att.toString() + "=" + payload[att];
}
if (queryString!="")
requestObj.url += "?" + queryString;
request.get(requestObj, function (err, resp, body){
if (err){
callback(err);
return;
}
callback(null, body);
});
break;
case "DELETE":
requestObj.body = payload;
request.del(requestObj, function (err, resp, body){
if (err){
callback(err);
return;
}
callback(null, body);
});
break;
}
}
更新:当前流程
client request1 -> Node
client request2 -> Node
Node server request1 ->backend
Node <- server response1 backend
client <- response1 Node
Node server request2 ->backend
Node <- server response2 backend
client <- response2 Node
我认为它应该是什么
client request1 -> Node
client request2 -> Node
Node server request1 -> backend
Node server request2 -> backend
Node <- server response2 backend
client <-response2 Node
Node <- server response1 backend
client <-response1 Node
您正在为requestAPI方法调用的每次调用创建一个新的代理实例(新池)。没有设置maxsockets的默认agentInstance的默认值为5。
可以增加全局代理的大小,如http.globalAgent.maxSockets
= Infinity或一个高值,具体取决于您的要求,并删除您创建的自定义池
或
在全局级别定义自定义池并设置maxsockets
var myAPIPool = new http.Agent({"maxSockets" : Infinity}); // Infinity or a high value depending on your res.
然后在方法
中使用这个变量var requestObj = {
url : targetUrl,
json : true,
pool: myAPIPool
}
在玩弄请求。js我来到以下实现。如果在请求模块上调用http方法,则需要使用on方法提供回调。例如。)
request.get(requestObj).on('response', function (response){
callback(null, body);
});
同样,您需要提供链接此模式的错误回调。ie)。on("error',cb)
等这将给你期望的行为。
更新:
我测试了以下代码,在没有任何代理的情况下对您的版本进行了轻微的调整。这清楚地记录了调用以及所有调用何时完成的日志S回调var request = require('request');
var http = require('http');
function apiService() {}
apiService.prototype.get = function(context, payload, callback, url) {
return this.requestAPI(context, payload, callback, url, "GET");
}
apiService.prototype.post = function(context, payload, callback, url) {
return this.requestAPI(context, payload, callback, url, "POST");
}
apiService.prototype.del = function(context, payload, callback, url) {
return this.requestAPI(context, payload, callback, url, "DELETE");
}
apiService.prototype.requestAPI = function(context, payload, callback, url, method) {
var requestObj = {
url: url,
json: true,
pool: new http.Agent()
}
switch (method) {
case "GET":
request.get(requestObj, function(err, resp, body) {
if (err) {
callback(err);
return;
}
callback(null, body);
});
break;
}
}
var apicaller = new apiService();
var url = "http://google.com";
var called = 0;
var cb = function() {
console.log("called once" + (called++));
}
console.log("calling");
apicaller.requestAPI(null, null, cb, url, "GET");
console.log("calling");
apicaller.requestAPI(null, null, cb, url, "GET");
console.log("calling");
apicaller.requestAPI(null, null, cb, url, "GET");
console.log("calling");
apicaller.requestAPI(null, null, cb, url, "GET");
console.log("calling");
apicaller.requestAPI(null, null, cb, url, "GET");
- node.js请求数据事件未在CORS ajax调用中触发
- JS请求-这是不是过时了
- 节点.js请求库的相对 URI
- 迭代node.js请求函数
- node.js请求返回对象
- Sails Js请求实体过大错误
- 节点js请求实体太大,需要多次上传
- 同步多个Js请求
- node.js请求js与curl相比失败
- node.js请求编码(谷歌翻译)
- node.js请求POST数组“;第一个参数必须是字符串或缓冲区;
- 从请求.js请求方法返回结果
- 视频.js 请求安卓 4 上的全屏
- 节点.js请求对象 - 返回响应正文以供进一步操作
- 如何将快递.js请求直接重定向到 404
- 处理基于javascript在轨道上开/关的HTML和JS请求
- 如何从节点.js请求对象读取数据事件(块)
- 快递.js请求正文__proto__
- 如何将每个快速 js 请求包装在域或 trycatch 中
- 客户端通过JS请求JSON并填充Rails视图