Я делаю длинный опрос с node.js.
В основном сервер node.js принимает запрос от пользователя и затем проверяет наличие некоторых обновлений. Если обновлений нет, они будут проверять их после таймаута.
Но что, если пользователь закрыл свою вкладку или перешел на другую страницу? В моем случае сценарий продолжает работать.
Есть ли способ в node.js проверить или обнаружить или поймать событие, когда пользователь прервал его запрос (закрыл соединение)?Как проверить, было ли соединение прервано на сервере node.js
ответ
Благодаря и ответы Miroshko в yojimbo87, я был в состоянии поймать «закрыть» событие, но я должен был сделать несколько дополнительных настроек.
Причина, по которой просто ловить «закрытие» события не устраняет мою проблему, заключается в том, что когда клиент отправляет запрос на сервер node.js, сам сервер не может получить информацию, если соединение все еще открыто до тех пор, пока он отправляет что-то обратно клиенту (насколько я понял - это из-за протокола HTTP).
Итак, дополнительная настройка заключалась в том, чтобы время от времени что-то писать.
Еще одна вещь, которая мешала этому работать, заключается в том, что у меня был «Content-type» как «application/json». Изменение его на «text/javascript» помогло время от времени потопить «пробелы», не закрывая соединение.
В конце концов, у меня было что-то вроде этого:
var server = http.createServer(function(req,res){
res.writeHead(200, {'Content-type': 'text/javascript'});
req.connection.on('close',function(){
// code to handle connection abort
});
/**
* Here goes some long polling handler
* that performs res.write(' '); from time to time
*/
// some another code...
});
server.listen(NODE_PORT, NODE_LISTEN_HOST);
Мой исходный код намного больше, так что мне пришлось сократить его много раз, чтобы показать чувствительные части.
Я хотел бы знать, есть ли лучшие решения, но это работает на меня сейчас.
Кажется, что ваш вопрос очень похож на этот:
NodeJS HTTP request connection's close event fired twice
попробовать
request.connection.on('close', function() {
...
});
Есть ли способ в Node.js для проверки или обнаружения или поймать событие, когда пользователь прервал его запрос (закрыл соединение)?
Вы можете использовать http.ServerRequest close event. Простой пример:
var http = require("http"),
util = require("util");
var httpServer = http.createServer(function(req, res) {
util.log("new request...");
// notify me when client connection is lost
req.on("close", function(err) {
util.log("request closed...");
});
// wait with response for 15 seconds
setTimeout(function() {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("response");
res.end();
util.log("response sent...");
}, 15000);
});
httpServer.listen(8080);
util.log("Running on 8080");
Вы должны использовать req.on('close', function(err) { ... });
вместо req.connection.on('close', function(err) { ... });
Существует очень важное различие. req.on() добавляет слушателя к этому запросу, а req.connection.on() добавляет слушателя к соединению (keep-alive) между клиентом и сервером. Если вы используете req.connection.on(), каждый раз, когда клиент повторно использует соединение, вы добавляете еще один прослушиватель к тому же соединению. Когда соединение окончательно отменено, все слушатели увольняются.
Область применения, как правило, защищает вас от этой логической ошибки сервера, но все же это опасно. К счастью, по крайней мере, NodeJS 0.10.26 достаточно умна, чтобы предупредить пользователя об этом:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace:
at Socket.EventEmitter.addListener (events.js:160:15)
at Socket.Readable.on (_stream_readable.js:689:33)
...
Я использую Express.js (~ 4.10.6) и следующий код работает отлично для меня: Как только
//GET Request:
app.get('/', function(req, res){
req.on('close', function(){
console.log('Client closed the connection');
});
});
когда я закрываю вкладку браузера, браузер закрывает соединение, и функция обратного вызова запускается, как и ожидалось.
- 1. Установленное соединение было прервано
- 2. net.tcp, соединение сокета было прервано
- 3. SFTP - соединение было прервано (C#)
- 4. WCF: Соединительное соединение было прервано
- 5. соединение гнездо было прервано - CommunicationException
- 6. Диагностика «Соединение с локальным хостом было прервано»
- 7. Безопасность транспорта WCF: соединение разъема было прервано
- 8. Соединение сокета было прервано. Возможное исключение SerializationException?
- 9. «Соединение с adb было прервано». ПРАВИЛЬНО
- 10. Соединение с разъемами было прервано - WCF
- 11. Чтение с удаленного хоста: соединение было прервано
- 12. Postgres libpq как сказать, если соединение было прервано
- 13. Boost asio «сетевое соединение было прервано локальной системой» на async_read_some
- 14. Соединение j_security_check прервано
- 15. WCF Server Автоматически подключается к клиенту, когда соединение было прервано
- 16. Как проверить, было ли приложение развернуто на определенном управляемом сервере?
- 17. Выполнение кода было прервано
- 18. Соединение SignalR прервано
- 19. Как проверить постоянное соединение на HTTP-сервере?
- 20. Django: Установленное соединение было прервано программным обеспечением вашей главной машины
- 21. Фотографии рамки: Соединение с активами было прервано или активы умерли
- 22. PHPMailer Установленное соединение было прервано программным обеспечением вашей главной машины
- 23. Соединение было прервано во время загрузки страницы - Firefox - Firebase - signInWithPopup()
- 24. socket.io Соединение с ws: // было прервано во время загрузки страницы
- 25. Установленное соединение было прервано программным обеспечением в главной машине
- 26. Установленное соединение было прервано программным обеспечением вашей главной машины Docker
- 27. Как я могу сказать, что соединение WCF на основе NetTcp было прервано?
- 28. Установленное соединение было прервано программным обеспечением вашей главной машины
- 29. java.io.IOException Установленное соединение было прервано программным обеспечением вашего хост-компьютера
- 30. PubSub соединение было прервано, когда страница была loadibng ошибки
На этой странице появилось больше информации о обнаружении закрытых TCP-соединений в целом: http://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html –