Node JS Soap Server(node-soap)从postgres回调传递值
Node JS Soap Server(node-soap) passing values from postgres callback
我有一个问题,我正在使用 node-soap 和 pg-promise。我有一个问题,当我向 soap 服务发出请求时,响应被延迟,换句话说,我必须在响应返回之前发送两次请求(使用 soap ui):
我想知道我是否没有将来自数据库调用的响应正确传递给节点 soap 回调:
以下是来自 node-soap 网站的示例代码:
var myService = {
MyService: {
MyPort: {
MyFunction: function(args) {
return {
name: args.name
};
},
// This is how to define an asynchronous function.
MyAsyncFunction: function(args, callback) {
// do some work
callback({
name: args.name
});
},
// This is how to receive incoming headers
HeadersAwareFunction: function(args, cb, headers) {
return {
name: headers.Token
};
},
// You can also inspect the original `req`
reallyDeatailedFunction: function(args, cb, headers, req) {
console.log('SOAP `reallyDeatailedFunction` request from + req.connection.remoteAddress);
return {
name: headers.Token
};
}
}
}
};
var xml = require('fs').readFileSync('myservice.wsdl', 'utf8'),
server = http.createServer(function(request,response) {
response.end("404: Not Found: " + request.url);
});
这是我的代码:
var http = require('http');
var soap = require('soap');
global.results = '';
var promise = require('bluebird'); //
var options = {
promiseLib: promise // switch to bluebird lib
};
// Database connection details;
var cn = {
host: '',
port: 5432,
database: '',
user: '',
password: ''
};
var pgp = require('pg-promise')(options);
var db = pgp(cn);
var cancelService = {
cancelService: {
Cancel_PortType: {
getAgreement: function(args,callback,headers) {
var values = {
vin: args.vin
};
db.any("select contract_num as contract, " +
"CASE WHEN sg_con_status='A' THEN 'Active ' " +
"WHEN sg_con_status='X' THEN 'Expired' " +
"WHEN sg_con_status='C' THEN 'Cancelled' " +
"END AS agreementStatus, " +
"tfs_product_type as productType, " +
"vin, cust_first_name as customerFirstName, cust_last_name as customerLastName," +
"TO_CHAR(original_busdate,'YYYY-MM-DD') as purchaseDate, TO_CHAR(expire_date,'YYYY-MM-DD') as expirationDate " +
"from tfs_contract_summary, sg_con_m1 where sg_con_m1.sg_con_contract = tfs_contract_summary.contract_num " +
" AND vin = ${vin}",values)
.then(function(data) {
//set value of DB return to global
global.results = data;
console.log("DATAAAAAAA:", data);
})
.catch(function(error) {
console.log("ERROR:", error); // print the error;
})
.finally(function() {
pgp.end(); //closing the connection pool.
});
// }
callback({
contracts: global.results
});
}
}
}
}
var xml = require('fs').readFileSync('CancelService.wsdl', 'utf8'),
server = http.createServer(function(request, response) {
response.end("404: Not Found: " + request.url)
});
server.listen(8000);
soap.listen(server, '/wsdl', cancelService, xml);
每次我在 SOAPUI 中发出请求时,我的所有 console.log() 都会显示返回的数据,但直到我第二次发送请求时才会返回响应:
例如
点击按钮一次:
vin = 12312364812736498
我希望 John doe 的信息 return -
console.log(李四的信息)
SOAP 响应 = 空
点击按钮两次
console.log(李四的信息)
SOAP RESPONSE = John doe 的信息
如果我使用提供的 soap 客户端示例代码并发出请求:
console.log 每次都有效:
我是否遇到 global.results 值存在竞争条件的范围问题???
我很确定我的代码可能有问题,因为我是 Node JS 等方面的新手...
我是否错误地传递给了 soap-server 的回调?
callback({
contracts: global.results
});
如有任何见解,我们将不胜感激。
我认为问题在于您在设置 global.results
之前调用回调函数(即使它位于函数的底部)。
你的 promise 的 .then
和 .catch
中的所有代码异步阻塞 运行 - 这意味着它们被拖到事件循环中 运行 之后;当前代码完成后。
这是您的代码中发生的顺序:
- 您启动了一个异步发生的数据库查询
- 你打电话给
callback({contracts: global.results})
。此时,global.results
未定义。
- 您的数据库查询完成,事件循环根据需要执行
.then
s 和 .catch
es。这是你设置 global.results
的地方(当然太晚了)
- 您向服务发出另一个请求 - 这次,
global.results
已设置为上次查询的结果。
解决方案是忘记使用 global
并将回调放在您的承诺的 .then
中:
db.any("my_awesome_sql")
.then(function(data) {
console.log("DATAAAAAAAA!!!", data);
callback({contracts: data});
})
.catch(function(error) {
// Handle error
})
.finally(function() {
// Cleanup
});
我有一个问题,我正在使用 node-soap 和 pg-promise。我有一个问题,当我向 soap 服务发出请求时,响应被延迟,换句话说,我必须在响应返回之前发送两次请求(使用 soap ui):
我想知道我是否没有将来自数据库调用的响应正确传递给节点 soap 回调:
以下是来自 node-soap 网站的示例代码:
var myService = {
MyService: {
MyPort: {
MyFunction: function(args) {
return {
name: args.name
};
},
// This is how to define an asynchronous function.
MyAsyncFunction: function(args, callback) {
// do some work
callback({
name: args.name
});
},
// This is how to receive incoming headers
HeadersAwareFunction: function(args, cb, headers) {
return {
name: headers.Token
};
},
// You can also inspect the original `req`
reallyDeatailedFunction: function(args, cb, headers, req) {
console.log('SOAP `reallyDeatailedFunction` request from + req.connection.remoteAddress);
return {
name: headers.Token
};
}
}
}
};
var xml = require('fs').readFileSync('myservice.wsdl', 'utf8'),
server = http.createServer(function(request,response) {
response.end("404: Not Found: " + request.url);
});
这是我的代码:
var http = require('http');
var soap = require('soap');
global.results = '';
var promise = require('bluebird'); //
var options = {
promiseLib: promise // switch to bluebird lib
};
// Database connection details;
var cn = {
host: '',
port: 5432,
database: '',
user: '',
password: ''
};
var pgp = require('pg-promise')(options);
var db = pgp(cn);
var cancelService = {
cancelService: {
Cancel_PortType: {
getAgreement: function(args,callback,headers) {
var values = {
vin: args.vin
};
db.any("select contract_num as contract, " +
"CASE WHEN sg_con_status='A' THEN 'Active ' " +
"WHEN sg_con_status='X' THEN 'Expired' " +
"WHEN sg_con_status='C' THEN 'Cancelled' " +
"END AS agreementStatus, " +
"tfs_product_type as productType, " +
"vin, cust_first_name as customerFirstName, cust_last_name as customerLastName," +
"TO_CHAR(original_busdate,'YYYY-MM-DD') as purchaseDate, TO_CHAR(expire_date,'YYYY-MM-DD') as expirationDate " +
"from tfs_contract_summary, sg_con_m1 where sg_con_m1.sg_con_contract = tfs_contract_summary.contract_num " +
" AND vin = ${vin}",values)
.then(function(data) {
//set value of DB return to global
global.results = data;
console.log("DATAAAAAAA:", data);
})
.catch(function(error) {
console.log("ERROR:", error); // print the error;
})
.finally(function() {
pgp.end(); //closing the connection pool.
});
// }
callback({
contracts: global.results
});
}
}
}
}
var xml = require('fs').readFileSync('CancelService.wsdl', 'utf8'),
server = http.createServer(function(request, response) {
response.end("404: Not Found: " + request.url)
});
server.listen(8000);
soap.listen(server, '/wsdl', cancelService, xml);
每次我在 SOAPUI 中发出请求时,我的所有 console.log() 都会显示返回的数据,但直到我第二次发送请求时才会返回响应:
例如
点击按钮一次: vin = 12312364812736498
我希望 John doe 的信息 return - console.log(李四的信息) SOAP 响应 = 空
点击按钮两次 console.log(李四的信息) SOAP RESPONSE = John doe 的信息
如果我使用提供的 soap 客户端示例代码并发出请求:
console.log 每次都有效:
我是否遇到 global.results 值存在竞争条件的范围问题???
我很确定我的代码可能有问题,因为我是 Node JS 等方面的新手...
我是否错误地传递给了 soap-server 的回调?
callback({
contracts: global.results
});
如有任何见解,我们将不胜感激。
我认为问题在于您在设置 global.results
之前调用回调函数(即使它位于函数的底部)。
你的 promise 的 .then
和 .catch
中的所有代码异步阻塞 运行 - 这意味着它们被拖到事件循环中 运行 之后;当前代码完成后。
这是您的代码中发生的顺序:
- 您启动了一个异步发生的数据库查询
- 你打电话给
callback({contracts: global.results})
。此时,global.results
未定义。 - 您的数据库查询完成,事件循环根据需要执行
.then
s 和.catch
es。这是你设置global.results
的地方(当然太晚了) - 您向服务发出另一个请求 - 这次,
global.results
已设置为上次查询的结果。
解决方案是忘记使用 global
并将回调放在您的承诺的 .then
中:
db.any("my_awesome_sql")
.then(function(data) {
console.log("DATAAAAAAAA!!!", data);
callback({contracts: data});
})
.catch(function(error) {
// Handle error
})
.finally(function() {
// Cleanup
});