javascript - nodejs - node js tiempo real
Manejo de solicitud cancelada con Express/Node.js y Angular (3)
Con Express, puedes probar:
req.connection.on(''close'',function(){
// code to handle connection abort
console.log(''user cancelled'');
});
Cuando un cliente / navegador cancela una solicitud HTTP pendiente, parece que Node with Express continúa procesando la solicitud. Para solicitudes intensivas, la CPU todavía se mantiene ocupada con solicitudes innecesarias.
¿Hay alguna forma de pedir a Node.js / Express que elimine / detenga estas solicitudes pendientes que se solicitan que se cancelen?
Se vuelve particularmente útil dado que la solicitud HTTP AngularJS 1.5 se puede cancellable fácilmente llamando a $cancelRequest()
en objetos de $resource
$http
/ $resource
.
Dichas cancelaciones podrían ocurrir al exponer un método API que proporciona resultados para la finalización automática o los campos de búsqueda: al escribir en el campo para autocompletar o adelantar, se pueden cancelar las solicitudes anteriores.
Un server.timeout
global no resuelve el problema: 1) a priori es una configuración global para todos los métodos API expuestos 2) el procesamiento continuo en la solicitud cancelada no se cancela.
El objeto req
inyectado se envía con escuchas .on()
.
El evento Listening to close
permite controlar cuándo el cliente cierra la conexión (solicitud cancelada por Angular o, por ejemplo, el usuario cerró la pestaña de consulta).
Aquí hay 2 ejemplos simples de cómo usar el evento de close
para detener el procesamiento de la solicitud.
Ejemplo 1: Bloque síncrono cancelable
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 */);
}
Ejemplo 2: Bloque asíncrono cancelable con promesas (análogo a una reducción)
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();
}