Node JS Soap Server(node-soap)从postgres回调传递值

时间:2016-02-10 17:10:04

标签: node.js soap pg-promise

我有一个问题,我正在使用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);

我的所有console.log()都显示每次在SOAPUI中发出请求时返回的数据,但响应在我发送请求的2次之后才会返回:

例如

按一下按钮: vin = 12312364812736498

我希望John doe信息能够返回 - console.log(John doe' s信息) SOAP RESPONSE =空

按两次按钮 console.log(John doe' s信息) SOAP RESPONSE = John doe的信息

如果我使用提供的soap客户端示例代码并发出请求:

console.log每次都有效:

我是否有范围问题,其中global.results值具有竞争条件?

我很确定我的代码可能有问题,因为我是Node JS等的新手......

我是否错误地传递了soap-server的回调?

callback({
            contracts: global.results
         });

非常感谢任何见解。

1 个答案:

答案 0 :(得分:1)

我认为问题是你在设置global.results之前调用了回调函数(即使它位于函数的底部)。

您的promise .then.catch块中的所有代码都是异步运行的 - 这意味着它们被拖拽到事件循环中以便稍后运行;在当前代码完成之后。

以下是代码中发生的事情的顺序:

  1. 启动异步发生的数据库查询
  2. 您致电callback({contracts: global.results})。此时,global.results未定义。
  3. 您的数据库查询完成后,事件循环会根据需要执行.then.catch es。这里是您设置global.results(当然为时已晚)
  4. 的地方
  5. 您向该服务发出另一个请求 - 这次,global.results已设置为上次查询的结果。
  6. 解决方法是忘记使用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
      });