Προγραμματισμός

Παρακολούθηση λήξης περιόδου λειτουργίας στο πρόγραμμα περιήγησης

Υπάρχει λοιπόν μια πολύπλοκη ετερογενής εφαρμογή ιστού, με εξαρτήματα AJAX να γίνονται χειροκίνητα και με πλαίσια, πολλαπλά αναδυόμενα παράθυρα κ.λπ. τα παράθυρα της εφαρμογής μόλις λήξει η περίοδος σύνδεσης HTTP. Ας ελπίσουμε ότι ξέρετε πώς να ελέγχετε το διάστημα χρονικού ορίου περιόδου σύνδεσης HTTP, για μια εφαρμογή Ιστού συμβατή με το J2EE γίνεται από ένα αρχείο web.xml (ωστόσο, σε πολλούς διακομιστές εφαρμογών δεν γίνεται με τυπικό τρόπο). Για χρονικό όριο 10 λεπτών είναι:

  10  

Η απαίτηση πελάτη δεν είναι καθόλου παράλογη και έχει νόημα από την οπτική γωνία του τελικού χρήστη, αλλά μπορεί να γίνει τρομερός πόνος για έναν προγραμματιστή επειδή: 1. Δεν μπορείτε απλώς να ξεκινήσετε ένα χρονόμετρο αντίστροφης μέτρησης στο παράθυρο του προγράμματος περιήγησης κάθε φορά που φορτώνεται η σελίδα για να κλείσετε το παράθυρο κατά τη λήξη του χρονικού ορίου. Αυτή η προσέγγιση λειτούργησε σε έναν κόσμο εκτός του AJAX όταν κάθε αλληλεπίδραση διακομιστή-διακομιστή είχε ως αποτέλεσμα την επαναφόρτωση του παραθύρου του προγράμματος περιήγησης. 2. Δεν μπορείτε να ρωτήσετε τον διακομιστή για να ελέγξετε εάν το χρονικό όριο της περιόδου σύνδεσης HTTP έχει λήξει ή όχι, καθώς κάθε τέτοιο ερώτημα θα αντιμετωπίζεται ως αλληλεπίδραση διακομιστή-διακομιστή που παρατείνει τη συνεδρία. Αυτό θα οδηγήσει σε μια συνεδρία που δεν λήγει ποτέ. 3. Θα μπορούσατε να δημιουργήσετε μια ξεχωριστή εφαρμογή ιστού έχοντας επίγνωση της αρχικής περιόδου σύνδεσης HTTP της εφαρμογής ιστού και τέμνοντάς την με αυτήν. Αλλά αυτό είναι υπερβολικό, και οι πιθανότητες μιας τέτοιας λύσης να γίνουν αποδεκτές είναι εξαιρετικά χαμηλές λόγω των προβλημάτων ολοκλήρωσης που ενδέχεται να προκύψουν. 4. Θα μπορούσατε να προσπαθήσετε να παρακολουθήσετε όλες τις αλληλεπιδράσεις του προγράμματος περιήγησης-διακομιστή AJAX με κάποιο προηγμένο κώδικα που μοιάζει με hack και θα σας βοηθήσει να αντιμετωπίσετε το τρέχον παράθυρο. Αλλά αυτό δεν λειτουργεί για τη θήκη πολλαπλών ανοιχτών παραθύρων - απλώς δεν μπορείτε να επικοινωνείτε μεταξύ των παραθύρων του προγράμματος περιήγησης. Ο μόνος τρόπος για να μιλήσετε σε κάποιο ανοιχτό παράθυρο από ένα πρωτεύον είναι να χρησιμοποιήσετε την αναφορά JavaScript άλλου παραθύρου και όταν το κύριο παράθυρο φορτωθεί ή κατευθυνθεί σε διαφορετική τοποθεσία χάνει όλες τις αναφορές JavaScript σε άλλα παράθυρα. 5. Η πιο ρεαλιστική προσέγγιση είναι να κάνετε περιοδικά αιτήματα JavaScript XMLHTTP (από κάθε ανοιχτό παράθυρο) στον διακομιστή κάθε {μέγιστο ανενεργό διάστημα συνεδρίας} +10 δευτερόλεπτα. Αυτό θα κλείσει τελικά όλα τα παράθυρα, αλλά μπορεί να οδηγήσει σε κλειστά παράθυρα λεπτά (ή ακόμα και ώρες ανάλογα με τη ρύθμιση χρονικού ορίου περιόδου λειτουργίας εφαρμογής ιστού) μετά την καταστροφή της περιόδου σύνδεσης HTTP, π.χ. όταν ο χρήστης αποσυνδεθεί από το κύριο παράθυρο. Δεν υπάρχουν άλλες επιλογές, είστε απογοητευμένοι και νομίζετε ότι είναι η κατάλληλη στιγμή να πάρετε το όπλο του μπαμπά σας και να πυροβολήσετε τους συμμαθητές σας στο σχολείο αύριο. Όχι, όχι ακόμα παιδί - υπάρχει ακόμα μια διέξοδος! Η διέξοδος δεν είναι πολύ απλή, αλλά είναι πολύ κομψή. Τα cookies θα μας βοηθήσουν. Θα μπορούσε κανείς να σκεφτεί ότι ο χρόνος λήξης των cookies θα έκανε το τέχνασμα. Δυστυχώς, όπως περιγράφεται στο

Αυτό

άρθρο, δεν μπορείτε να βασιστείτε στον χρόνο λήξης των cookie, δεδομένου ότι μετράται από πρόγραμμα περιήγησης πελάτη και κανείς δεν μπορεί να εγγυηθεί ότι το ρολόι συστήματος πελάτη δεν είναι ένα χρόνο πίσω. Λοιπόν, εδώ είναι το Σύστημα και η Μέθοδος Παρακολούθησης Χρονικών Διακοπών περιόδου σύνδεσης HTTP σε ετερογενείς εφαρμογές Ιστού. Σε κάθε αίτημα που υποβάλλεται από πρόγραμμα περιήγησης σε διακομιστή, δύο cookie ορίζονται από ένα φίλτρο servlet. Το ένα κρατά την τρέχουσα ώρα του διακομιστή και το άλλο κρατά την ώρα λήξης της περιόδου λειτουργίας. Ο τρέχων χρόνος διακομιστή απαιτείται μόνο για τον υπολογισμό μιας μετατόπισης μεταξύ πελάτη και διακομιστή. Ο χρόνος λήξης περιόδου σύνδεσης ελέγχεται περιοδικά έναντι του _calculated_ τρέχοντος χρόνου διακομιστή (θυμηθείτε την μετατόπιση). Κάθε φορά που υποβάλλεται αίτημα _any_ στον διακομιστή, το cookie χρόνου λήξης ενημερώνεται και το όλο πράγμα λειτουργεί. Στην πράξη, αυτή η μέθοδος πραγματοποιείται σε τρία μόνο βήματα: 1. Δημιουργήστε ένα φίλτρο servlet που θα φιλτράρει κάθε αίτημα στην εφαρμογή ιστού σας. Διαμορφώστε το στο web.xml ως εξής:

  SessionTimeoutCookieFilter some.package.SessionTimeoutCookieFilter SessionTimeoutCookieFilter / * 

Μην ανησυχείτε για την απόδοση της εφαρμογής ιστού - αυτό το φίλτρο είναι ΠΟΛΥ πρωτόγονο, το μόνο που κάνει είναι να προσθέσετε δύο cookie στην απάντηση:

 public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterChain) ρίχνει το IOException, ServletException {HttpServletResponse httpResp = (HttpServletResponse) resp; HttpServletRequest httpReq = (HttpServletRequest) req; long currTime = System.currentTimeMillis (); long expiryTime = currTime + session.getMaxInactiveInterval () * 1000; Cookie cookie = νέο Cookie ("serverTime", "" + currTime); cookie.setPath ("/"); httpResp.addCookie (cookie); εάν (httpReq.getRemoteUser ()! = null) {cookie = νέο Cookie ("sessionExpiry", "" + expiryTime); } αλλιώς {cookie = νέο Cookie ("sessionExpiry", "" + currTime); } cookie.setPath ("/"); httpResponse.addCookie (cookie); filterChain.doFilter (req, resp); } 

Η ρύθμιση της διαδρομής (στο "/" στην περίπτωσή μας) είναι πολύ σημαντική. Εάν παραλείψετε τη ρύθμιση της διαδρομής, το πρόγραμμα περιήγησης θα το υπολογίσει αυτόματα από τη διεύθυνση URL που θα οδηγήσει σε χάος στο χώρο αποθήκευσης των cookie του προγράμματος περιήγησής σας. 2. Χρειαζόμαστε ένα μικρό JavaScript σε κάθε παράθυρο για τον υπολογισμό της μετατόπισης μεταξύ του διακομιστή και του χρόνου του πελάτη. Πρέπει να εκτελείται μόνο μία φορά, αλλά δεν θα ήταν κακό να εκτελείται σε κάθε φόρτωση σελίδας:

 συνάρτηση calcOffset () {var serverTime = getCookie ('serverTime'); serverTime = serverTime == null; null: Math.abs (serverTime); var clientTimeOffset = (νέα ημερομηνία ()). getTime () - serverTime; setCookie ('clientTimeOffset', clientTimeOffset); } window.onLoad = συνάρτηση () {calcOffset (); }; 

3. Και τέλος χρειαζόμαστε μια συνάρτηση που θα ελέγχει αν η περίοδος λειτουργίας έχει λήξει. Πρέπει να εκτελείται περιοδικά, στην περίπτωσή μας κάθε 10 δευτερόλεπτα (ή 10000 χιλιοστά του δευτερολέπτου):

 function checkSession () {var sessionExpiry = Math.abs (getCookie ('sessionExpiry')); var timeOffset = Math.abs (getCookie ('clientTimeOffset')); var localTime = (νέα ημερομηνία ()). getTime (); if (localTime - timeOffset> (sessionExpiry + 15000)) {// 15 επιπλέον δευτερόλεπτα για να βεβαιωθείτε ότι το window.close (); } αλλιώς {setTimeout ('checkSession ()', 10000); }} 

Πράγματι, το κλείσιμο των παραθύρων του προγράμματος περιήγησης κατά τη λήξη της περιόδου σύνδεσης είναι καθαρή βαρβαρότητα και μπορεί και πρέπει να συνοδεύεται από ένα προειδοποιητικό μήνυμα που εμφανίζεται σαν 1 λεπτό πριν από τη λήξη της περιόδου λειτουργίας. Ενδιαφέρομαι πραγματικά να λάβω το δικό σας

κριτική κριτική

στη μέθοδο μου.

Αυτή η ιστορία, "Παρακολούθηση λήξης περιόδου λειτουργίας στο πρόγραμμα περιήγησης" δημοσιεύθηκε αρχικά από το JavaWorld