Dartlang服务器不止一次调用我的函数

时间:2014-10-21 08:09:32

标签: dart dart-async

我正在向服务器发送数据:

 save(){ 
   var el = this.parent.nodes;
   print(el);print(el.length);
   request = new HttpRequest();
    if(el.length == 1) print('No lines to save!');
     else           
     {        
      var opt = el[i].shadowRoot.nodes[0].options[el[i].shadowRoot.nodes[0].selectedIndex].text;
      print(this.parent.nodes.length);
      for(var i=1; i < el.length; i++)
             {                         
                        orderLines.add({ 
                             'poid': orderHeader[0]['OrderID'],
                            'ponum': orderHeader[0]['onum'],
                            'lnum' : i.toString(),
                           'itmid' :el[i].shadowRoot.nodes[0].value,
                           'icode' : opt,
                              'qty': el[i].shadowRoot.nodes[1].value,
                             'rqty': 0,
                             'bqty': el[i].shadowRoot.nodes[1].value,
                             'iqty': 0,
                            'biqty': el[i].shadowRoot.nodes[1].value,
                            'price': el[i].shadowRoot.nodes[2].value,
                              'rdd': orderHeader[0]['rdd'],
                              'eta': '',
                             'flag': 0 
                                        });  

                        print(orderLines);

                        request.onReadyStateChange.listen(onData_save);   
                        request.open('POST', host+'/sPO');
                        request.send(JSON.encode(orderLines));  
               }
      }
  }

我的服务器端功能是:

void main() {
  connections = new List<WebSocket>();

  HttpServer.bind(HOST, PORT).then((HttpServer server) {
   print('Server listening on port ${PORT}.');
   server.listen((HttpRequest request) {
    if (WebSocketTransformer.isUpgradeRequest(request)) {
      WebSocketTransformer.upgrade(request).then(handleWS); 
    } else gotMSG(request);        
    });
  }); 
}

handleWS(WebSocket ws){

connections.add(ws);
print('Client connected, there are now ${connections.length} client(s) connected.');
ws.listen((String message) {
  for (WebSocket connection in connections) {
  connection.add(message);
  }
},
onDone: () {
 connections.remove(ws);
 print('Client disconnected, there are now ${connections.length} client(s) connected.');
});
}

 void gotMSG(HttpRequest request) {
 switch (request.method) {
  case 'POST': 
    handlePost(request);
    break;
  case 'OPTIONS':
    handleOptions(request);
    break;
  default:
    defaultHandler(request);
 }
}

void serveRequest(HttpRequest request){
  print('Listening for GET and POST on http://$HOST:$PORT');
  request.response.statusCode = HttpStatus.FORBIDDEN;
   request.response.reasonPhrase = "WebSocket connections only";
   request.response.close();  
}

void handlePost(HttpRequest req) {
  HttpResponse res = req.response;
     switch (req.uri.path) {

       case '/login': login(req); break;
       ...
       case '/sPO': savePO(req); break;

       default: break;
     }     
}

/ sPO =&gt;如果发送的订单只有一行,则savePO执行一次,但如果订单中有n行,则该函数执行多次,找不到该模式, 在SavePO中我使用了oracledart pub,所以认为它有问题,并尝试了postgresql pub,但得到了相同的结果,savePO函数是:

void savePO(HttpRequest req){

 HttpResponse res = req.response;
 addCorsHeaders(res);
 print('${req.method}: ${req.uri.path}');

 Future future() => new Future.value(true);

 req.listen((List<int> buffer) {
 var theDataLines = JSON.decode(new String.fromCharCodes(buffer));
 print(theDataLines);
        connect(db).then((conn) {  
          for (var theData in theDataLines)
               conn.execute("""
                      insert into pol 
                             (poid,ponum,lnum,itmid,icode,qty,rqty,bqty,iqty,biqty,price,rdd, eta, flag)
                      values (@poid,@ponum,@lnum,@itmid,@icode,@qty,@rqty,@bqty,@iqty,@biqty,@price,
                              to_timestamp(@rdd,'YYYY-MM-DD'), to_timestamp(@eta,'YYYY-MM-DD'), @flag)
                   """,
                {                     
                      'poid': theData['poid'],
                     'ponum': theData['ponum'],
                     'lnum' : theData['lnum'],
                    'itmid' : theData['itmid'],
                    'icode' : theData['icode'],
                       'qty': theData['qty'],
                      'rqty': theData['rqty'],
                      'bqty': theData['bqty'],
                      'iqty': theData['iqty'],
                     'biqty': theData['biqty'],
                     'price': theData['price'],
                       'rdd': theData['rdd'].toString(),
                       'eta': theData['eta'].toString(),
                      'flag': theData['flag']
                 })
        .then((_)=>conn.query('commit').toList().then((rows) {print('committed');}))
        .then((_){
                    res.write('done');
                    res.close(); 
               });
    });    // END of SQL
  }, onError: printError);  // End of server listen
 }  // END of function

我甚至试图改变:

case '/sPO': savePO(req); break;

case '/sPO': print(1); break;

在发出6行订单后打印了1,4次!!

1 个答案:

答案 0 :(得分:0)

我很难看到你真正想要实现的目标。

问题很可能是你的save()方法。你写了它的表现方式,但没有太多关于你想要完成的事情? 为什么不将更多行放入一个JSON字符串并在一个请求中将它们一起发布?

您创建了一个request实例,并在此send个实例上重复调用request。 您还在同一个请求对象上多次注册onReadyStateChange处理程序,这导致在事件发生一次时多次调用onData_save

我认为您应该在

之前移动request = new HttpRequest();
request.open('POST', host+'/sPO');
request.send(JSON.encode(orderLines));  

或更好地将request.onReadyStateChange.listen(onData_save);移至request = new HttpRequest();, 将所有订单行添加到一个JSON中并调用

request.open('POST', host+'/sPO');
request.send(JSON.encode(orderLines));  
在for循环之后

我看到的另一个问题是你做了火并忘了。如果发送请求由于某种原因失败怎么办?

我会创建一个sendJSON方法,该方法返回一个未来(当出现问题时,完成时会在onDonecompleteError完成。

如果您想在save()中创建多个请求,可以使用类似

的内容
// create your JSON

var futures = [];
for(i = 0; i < 5; i++) {
  futures.add(sendData(myJson)); // collects the futures returned from sendData
}
// executes all futures and waits for all to respond and then returns another future
return Future.wait()
.then((results) {
  results.forEach((r) {
    // check result
  });
});