Robię długiej ankietę za pomocą node.js.
Zasadniczo serwer node.js przyjmuje żądanie od użytkownika, a następnie sprawdza niektóre aktualizacje. Jeśli nie ma żadnych aktualizacji, sprawdzi je po przekroczeniu limitu czasu.
Ale co, jeśli użytkownik zamknął swoją kartę lub przeszedł do innej strony? W moim przypadku skrypt nadal działa.
Czy jest jakiś sposób w pliku node.js, aby sprawdzić lub wykryć lub złapać zdarzenie, gdy użytkownik przerwał swoje żądanie (zamknął połączenie)?Jak sprawdzić, czy połączenie zostało przerwane na serwerze node.js
Odpowiedz
Dzięki Miroshko za i yojimbo87 za odpowiedzi udało mi się złapać „bliskie” zdarzenie, ale musiałem zrobić kilka dodatkowych usprawnień.
Powodem, dla którego samo uchwycenie zdarzenia "zamknięcie" nie rozwiązało problemu, jest to, że gdy klient wysyła żądanie do serwera node.js, sam serwer nie może uzyskać informacji, jeśli połączenie jest nadal otwarte, dopóki wysyła coś z powrotem do klienta (o ile zrozumiałem - wynika to z protokołu HTTP).
Tak więc dodatkową zmianą było od czasu do czasu napisanie czegoś do odpowiedzi.
Jeszcze jedną rzeczą, która uniemożliwiła to działanie, jest to, że miałem "Content-type" jako "application/json". Zmiana na "text/javascript" pomogła w streamowaniu "białych przestrzeni" od czasu do czasu bez zamykania połączenia.
W końcu miałem coś takiego:
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);
Mój oryginalny kod jest znacznie większy, więc musiałem go wyciąć wiele prostu pokazać wrażliwych części.
Chciałbym wiedzieć, czy istnieją lepsze rozwiązania, ale teraz to działa dla mnie.
Wydaje się, że pytanie jest bardzo podobne do tego:
NodeJS HTTP request connection's close event fired twice
spróbować
request.connection.on('close', function() {
...
});
Czy istnieje sposób w node.js sprawdzić lub wykryć lub złapać zdarzenie, gdy użytkownik przerwał swoją prośbę (zamknął połączenie)?
Możesz spróbować użyć http.ServerRequest close event. Prosty przykład:
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");
Trzeba użyć req.on('close', function(err) { ... });
zamiast req.connection.on('close', function(err) { ... });
Jest to bardzo ważne rozróżnienie. req.on() dodaje detektora do tego żądania, podczas gdy req.connection.on(), dodaje detektor do połączenia (keep-alive) między klientem a serwerem. Jeśli używasz komendy req.connection.on(), za każdym razem, gdy klient ponownie używa połączenia, dodajesz jeszcze jednego detektora do tego samego połączenia. Kiedy połączenie zostanie ostatecznie przerwane, wszyscy słuchacze zostają zwolnieni.
Scoping funkcji zwykle chroni przed tym, że wkręca się logika serwera, ale mimo to jest to niebezpieczne. Na szczęście przynajmniej NodeJS 0.10.26 jest na tyle silny, aby ostrzec użytkownika o tym:
(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)
...
Używam Express.js (~ 4.10.6) i następujący kod działa dobrze dla mnie:
//GET Request:
app.get('/', function(req, res){
req.on('close', function(){
console.log('Client closed the connection');
});
});
Niezwłocznie po zamknięciu karty przeglądarki przeglądarka zamyka połączenie, a funkcja wywołania zwrotnego zostaje wykonana zgodnie z oczekiwaniami.
- 1. Jak stwierdzić, czy JQuery błąd oznacza połączenie zostało przerwane
- 2. Jak sprawdzić, czy połączenie SSH zostało ustanowione z instancją AWS
- 3. Schemat zdjęć: Połączenie z assetd zostało przerwane lub assetsd zmarł
- 4. Utworzone połączenie zostało przerwane przez oprogramowanie komputera-hosta tomcat jackson
- 5. socket.io Połączenie z ws: // zostało przerwane podczas ładowania strony
- 6. System.Net.WebException: żądanie zostało przerwane: żądanie zostało anulowane
- 7. Jak sprawdzić, czy połączenie MongoDB jest żywe w Node.js
- 8. Python requests.exception.ConnectionError: połączenie przerwane "BadStatusLine"
- 9. Czy Node.js można uruchomić na serwerze Tomcat?
- 10. Kolba - socket.error: [ERRNO 10053] Nawiązane połączenie zostało przerwane przez oprogramowanie w komputerze hosta
- 11. Jak zaimplementować nagrywanie WebRTC na serwerze Node.js
- 12. Weryfikacja CSRF nie powiodła się. Żądanie zostało przerwane. na django
- 13. Pierwsze "podstawowe połączenie zostało zamknięte" na HttpWebRequest
- 14. Node.js - serwer zamknął połączenie?
- 15. Xamarin.Forms Previewer "Połączenie zostało zamknięte"
- 16. czytanie strumienia utworzonego przez urllib2 nigdy się nie odtwarza, gdy połączenie zostało przerwane
- 17. Jak mogę sprawdzić, czy połączenie używa ssl?
- 18. Żądanie zostało przerwane: Nie można utworzyć bezpiecznego kanału SSL/TLS
- 19. iOS: błąd w __connection_block_invoke_2: Połączenie przerwane
- 20. Python Żąda pobrania ("Połączenie przerwane.", BadStatusLine ("" ",)) error
- 21. Gdzie rozmieścić aplikacje node.js na serwerze Linux?
- 22. Jak sprawdzić lokalnie połączenie socket.io?
- 23. Jak wykryć przerwane/odzyskane połączenie JMS w Apache Camel?
- 24. jak sprawdzić, czy subskrybowanie zostało zakończone, ładowanie wszystkich istniejących wierszy?
- 25. Jak mogę sprawdzić, czy okno zostało zamknięte w JavaScript?
- 26. Jak sprawdzić, czy zostało utworzone okno dialogowe GTK +?
- 27. Swift rozszerzenie klawiatury SIGQUIT, wykonanie zostało przerwane, powód: EXC_BREAKPOINT
- 28. Jak sprawdzić, czy połączenie wychodzące jest odbierane, w systemie Android?
- 29. Jak mogę sprawdzić, czy zostało załadowane okno dialogowe Dojo?
- 30. Jak mogę sprawdzić, czy zapytanie dialogowe jquery ui zostało zainicjowane?
Ta strona zawiera więcej informacji na temat wykrywania zamkniętych połączeń TCP w ogóle: http://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html –