2016-02-04 16 views
13

के साथ रद्द किए गए अनुरोध को संभालने पर क्लाइंट/ब्राउज़र द्वारा लंबित HTTP अनुरोध रद्द कर दिया गया है, ऐसा लगता है कि एक्सप्रेस के साथ नोड अनुरोध को संसाधित करता रहा है। गहन अनुरोधों के लिए, सीपीयू को अभी भी अनावश्यक अनुरोधों के साथ व्यस्त रखा जा रहा है।एक्सप्रेस/नोड.जेएस और कोणीय

क्या इन लंबित अनुरोधों को रद्द/रोकने के लिए नोड.जेएस/एक्सप्रेस से पूछने का कोई तरीका है जिन्हें रद्द करने का अनुरोध किया गया है?

यह दिया विशेष रूप से उपयोगी हो जाता है कि AngularJS 1.5 HTTP अनुरोध $http/$resource वस्तुओं पर $cancelRequest() फोन करके आसानी से cancellable हैं के बाद से।

ऐसी रद्दीकरण तब हो सकती है जब एपीआई विधि को स्वत: पूर्णता या खोज फ़ील्ड के परिणाम प्रदान करते हैं: जब फ़ील्ड में स्वत: पूर्ण या टाइप-अग्रेषित होने के लिए टाइप करते समय, पिछले अनुरोध को रद्द कर दिया जा सकता है।

एक वैश्विक server.timeout समस्या का समाधान नहीं करता है: 1) यह एक प्रायोरी रद्द अनुरोध में सभी उजागर एपीआई तरीकों 2) चल रही प्रक्रिया के लिए एक वैश्विक सेटिंग को मार डाला नहीं है।

उत्तर

9

इंजेक्ट req वस्तु श्रोताओं .on() के साथ भेज दिया है।

close ईवेंट सुनना जब ग्राहक कनेक्शन बंद कर देता है (कोणीय द्वारा अनुरोध रद्द किया गया है या, उदाहरण के लिए, उपयोगकर्ता क्वेरीिंग टैब बंद कर देता है)।

अनुरोध प्रक्रिया को रोकने के लिए close ईवेंट का उपयोग करने के लिए यहां 2 सरल उदाहरण दिए गए हैं।

उदाहरण 1: रद्द करने योग्य तुल्यकालिक ब्लॉक

var clientCancelledRequest = 'clientCancelledRequest'; 

function cancellableAPIMethodA(req, res, next) { 
    var cancelRequest = false; 

    req.on('close', function (err){ 
     cancelRequest = true; 
    }); 

    var superLargeArray = [/* ... */]; 

    try { 
     // Long processing loop 
     superLargeArray.forEach(function (item) { 
       if (cancelRequest) { 
        throw {type: clientCancelledRequest}; 
       } 
       /* Work on item */ 
     }); 

     // Job done before client cancelled the request, send result to client 
     res.send(/* results */); 
    } catch (e) { 
     // Re-throw (or call next(e)) on non-cancellation exception 
     if (e.type !== clientCancelledRequest) { 
      throw e; 
     } 
    } 

    // Job done before client cancelled the request, send result to client 
    res.send(/* results */); 
} 

उदाहरण 2: वादे के साथ रद्द करने योग्य अतुल्यकालिक ब्लॉक (एक कम करने के लिए एनालॉग)

function cancellableAPIMethodA(req, res, next) { 
    var cancelRequest = false; 

    req.on('close', function (err){ 
     cancelRequest = true; 
    }); 

    var superLargeArray = [/* ... */]; 

    var promise = Q.when(); 
    superLargeArray.forEach(function (item) { 
      promise = promise.then(function() { 
       if (cancelRequest) { 
        throw {type: clientCancelledRequest}; 
       } 
       /* Work on item */ 
      }); 
    }); 

    promise.then(function() { 
     // Job done before client cancelled the request, send result to client 
     res.send(/* results */); 
    }) 
    .catch(function(err) { 
     // Re-throw (or call next(err)) on non-cancellation exception 
     if (err.type !== clientCancelledRequest) { 
      throw err; 
     } 
    }) 
    .done(); 
} 
+0

आप "बंद" के बजाय 'निरस्त" 'के लिए सुनना चाहेंगे। https://nodejs.org/api/http.html#http_event_aborted – ZachB

0

आप अपने सर्वर पर अनुरोधों के लिए एक timeout सेट कर सकते हैं:

var server = app.listen(app.get('port'), function() { 
    debug('Express server listening on port ' + server.address().port); 
}); 
// Set the timeout for a request to 1sec 
server.timeout = 1000; 
+0

जैसे ही ग्राहक इसे रद्द करने के लिए कहता है, मैं एक अनुरोध रद्द करना चाहता हूं। स्वत: पूर्णता के लिए प्रश्नों के साथ उपयोगी। – Derek

+0

मैंने इस स्थिति के बारे में प्रश्न में कुछ टिप्पणियां जोड़े हैं: एक वैश्विक सर्वर। टाइमआउट समस्या का समाधान नहीं करता है: 1) यह सभी पूर्ववर्ती एपीआई विधियों के लिए एक वैश्विक सेटिंग है। 2) रद्द किए गए अनुरोध में चल रही प्रसंस्करण नहीं है । – Derek

+0

धन्यवाद। मैं इस पर गौर करूंगा। – gnerkus

4

एक्सप्रेस के साथ, आप की कोशिश कर सकते हैं:

req.connection.on('close',function(){  
    // code to handle connection abort 
    console.log('user cancelled'); 
}); 
संबंधित मुद्दे