Long Polling είναι μια τεχνική αλληλεπίδρασης πελάτη και διακομιστή κατά την οποία ο διακομιστής διατηρεί ανοιχτό το αίτημα HTTP μέχρι να εμφανιστούν νέα δεδομένα ή να λήξει το timeout. Σε αντίθεση με την περιοδική polling, ο διακομιστής δεν επιστρέφει αμέσως κενή απάντηση, αλλά περιμένει την εκδήλωση ενός συμβάντος για να στείλει δεδομένα στον πελάτη. Σύμφωνα με το MDN Web Docs, 2024, το Long Polling παραμένει μια περιζήτητη λύση για εφαρμογές πραγματικού χρόνου όπου το WebSocket δεν είναι διαθέσιμο ή είναι περιττό.
Κύρια σημεία
Long Polling είναι ένα μοτίβο αλληλεπίδρασης στην αρχιτεκτονική πελάτη-διακομιστή όπου ο πελάτης εκκινεί ένα αίτημα HTTP και ο διακομιστής καθυστερεί την αποστολή της απάντησης μέχρι να εμφανιστούν νέα δεδομένα ή να λήξει ένα καθορισμένο timeout. Μετά τη λήψη της απάντησης, ο πελάτης στέλνει αμέσως το επόμενο αίτημα, δημιουργώντας την εντύπωση συνεχούς σύνδεσης.
Η τεχνική Long Polling εμφανίστηκε ως εξελικτική ανάπτυξη του Short Polling για τη μείωση του αριθμού των κενών αιτημάτων HTTP. Στην παραδοσιακή polling, ο πελάτης στέλνει αιτήματα κάθε N δευτερόλεπτα και ο διακομιστής απαντά ακόμα και όταν δεν υπάρχουν νέα δεδομένα. Στο Long Polling, ο διακομιστής χρησιμοποιεί έναν μηχανισμό διατήρησης σύνδεσης, που μειώνει ριζικά τον όγκο της άχρηστης κίνησης.
Πριν από την εμφάνιση του WebSocket το 2011, το Long Polling ήταν η κύρια μέθοδος οργάνωσης πραγματικού χρόνου στον ιστό. Εταιρείες όπως το Facebook και το Gmail χρησιμοποίησαν αυτήν την τεχνική για τα chat και τις ειδοποιήσεις τους στις αρχές της δεκαετίας του 2010. Σύμφωνα με την έρευνα High Performance Browser Networking (Grigorik, 2013), το Long Polling επεξεργαζόταν έως και το 95% όλων των συνδέσεων πραγματικού χρόνου σε μεγάλες εφαρμογές ιστού εκείνης της περιόδου.
Ο πελάτης στέλνει ένα τυπικό αίτημα HTTP στον διακομιστή. Ο διακομιστής, μετά τη λήψη του αιτήματος, δεν επιστρέφει αμέσως απάντηση — τοποθετεί το αίτημα σε ουρά αναμονής. Όταν συμβεί ένα συμβάν στον διακομιστή (νέο μήνυμα, αλλαγή δεδομένων), ο διακομιστής σχηματίζει την απάντηση και τη στέλνει στον πελάτη. Ο πελάτης, μετά τη λήψη της απάντησης, δημιουργεί αμέσως ένα νέο αίτημα Long Polling και ο κύκλος επαναλαμβάνεται.
Long Polling λειτουργεί σύμφωνα με την ακόλουθη σειρά βημάτων. Ο πελάτης στέλνει ένα αίτημα HTTP GET στο endpoint του διακομιστή. Ο διακομιστής, μετά τη λήψη του αιτήματος, ελέγχει τη διαθεσιμότητα νέων δεδομένων στην ουρά συμβάντων. Εάν δεν υπάρχουν δεδομένα, ο διακομιστής διατηρεί το αίτημα σε κατάσταση αναμονής, χωρίς να στέλνει αμέσως απάντηση. Ο μηχανισμός διατήρησης εξαρτάται από την υλοποίηση του διακομιστή — πιο συχνά χρησιμοποιείται ασύγχρονη επεξεργασία με callbacks ή αρχιτεκτονική βασισμένη σε συμβάντα.
Όταν συμβεί ένα συμβάν στην πλευρά του διακομιστή (για παράδειγμα, ο χρήστης έστειλε ένα μήνυμα στο chat), ο διακομιστής σχηματίζει μια απάντηση HTTP με σώμα που περιέχει αυτά τα δεδομένα και τερματίζει τη σύνδεση. Ο πελάτης λαμβάνει την απάντηση, επεξεργάζεται τα δεδομένα και εκκινεί αμέσως ένα νέο αίτημα. Εάν κατά τη διάρκεια της αναμονής δεν εμφανίστηκαν δεδομένα, ο διακομιστής στέλνει μια κενή απάντηση μετά τη λήξη του timeout και ο πελάτης επίσης επαναδημιουργεί τη σύνδεση. Το timeout είναι συνήθως 30-60 δευτερόλεπτα για ισορροπία μεταξύ φορτίου και καθυστέρησης.
Η βασική παράμετρος διαμόρφωσης του Long Polling είναι το timeout αναμονής. Πολύ σύντομο timeout (λιγότερο από 10 δευτερόλεπτα) οδηγεί σε αύξηση του αριθμού αιτημάτων, προσεγγίζοντας την τεχνική στο Short Polling. Πολύ μεγάλο (περισσότερο από 120 δευτερόλεπτα) μπορεί να προκαλέσει διακοπή της σύνδεσης από ενδιάμεσα proxy και load balancer. Η συνιστώμενη τιμή για τα περισσότερα σενάρια είναι 30-45 δευτερόλεπτα.
Εάν συνέβησαν πολλά συμβάντα στον διακομιστή κατά τη διάρκεια ενός αιτήματος Long Polling, ο διακομιστής πρέπει να τα μεταδώσει όλα σε μία απάντηση ή να οργανώσει μια ουρά συμβάντων στην πλευρά του πελάτη. Γι' αυτό χρησιμοποιείται προσωρινή αποθήκευση συμβάντων: ο διακομιστής συλλέγει τα συμβάντα που συνέβησαν κατά τη διάρκεια διατήρησης του αιτήματος και τα μεταδίδει ως πίνακα δεδομένων στο σώμα της απάντησης.
Ας εξετάσουμε μια απλή υλοποίηση Long Polling στην πλευρά του πελάτη χρησιμοποιώντας το σύγχρονο Fetch API. Η συνάρτηση πελάτη στέλνει ένα αίτημα και καλεί αναδρομικά τον εαυτό της μετά τη λήψη της απάντησης.
async function longPoll(url) {
try {
const response = await fetch(url);
const data = await response.json();
handleData(data);
longPoll(url);
} catch (error) {
console.error("Σφάλμα Long Polling", error);
setTimeout(() => longPoll(url), 3000);
}
}
function handleData(data) {
if (data.events && data.events.length > 0) {
data.events.forEach(event => {
console.log("Νέο συμβάν:", event);
});
}
}
longPoll("/api/events");
Αυτός ο κώδικας δημιουργεί έναν ατέρμονο βρόχο Long Polling: μετά τη λήψη της απάντησης, η συνάρτηση στέλνει αμέσως ένα νέο αίτημα. Σε περίπτωση σφάλματος σύνδεσης, ορίζεται μια καθυστέρηση τριών δευτερολέπτων πριν από την εκ νέου προσπάθεια για να αποφευχθεί η χιονοστιβάδα φορτίου στον διακομιστή.
Στην πλευρά του διακομιστή, το αίτημα πρέπει να διατηρηθεί μέχρι να εμφανιστεί ένα συμβάν ή να λήξει το timeout. Ένα παράδειγμα υλοποίησης με χρήση EventEmitter σε Node.js δείχνει αυτόν τον μηχανισμό.
const express = require("express");
const EventEmitter = require("events");
const app = express();
const eventBus = new EventEmitter();
app.get("/api/events", (req, res) => {
const timeout = setTimeout(() => {
res.json({ events: [] });
}, 30000);
eventBus.once("new-event", (data) => {
clearTimeout(timeout);
res.json({ events: [data] });
});
});
app.post("/api/events", (req, res) => {
eventBus.emit("new-event", req.body);
res.send({ status: "ok" });
});
app.listen(3000);
Το τμήμα διακομιστή χρησιμοποιεί το EventEmitter για να ειδοποιεί τις αναμένουσες συνδέσεις Long Polling όταν εμφανίζονται νέα δεδομένα. Με την επίτευξη του timeout των 30 δευτερολέπτων, ο διακομιστής επιστρέφει έναν κενό πίνακα συμβάντων και ο πελάτης δημιουργεί ένα νέο αίτημα.
Long Polling εφαρμόζεται σε σενάρια όπου απαιτείται παράδοση δεδομένων σε πραγματικό χρόνο, αλλά η χρήση WebSocket είναι αδύνατη για τεχνικούς ή υποδομής λόγους. Οι πιο συνηθισμένες περιπτώσεις — εταιρικά proxy και τείχη προστασίας που μπλοκάρουν συνδέσεις WebSocket, καθώς και περιβάλλοντα με περιορισμένη υποστήριξη πρωτοκόλλου από την πλευρά του διακομιστή.
Ο βασικός παράγοντας επιλογής του Long Polling είναι η συμβατότητα προς τα πίσω. Όλοι οι πελάτες και διακομιστές HTTP υποστηρίζουν αυτήν τη μέθοδο, καθιστώντας την μια καθολική λύση για πραγματικό χρόνο χωρίς πρόσθετες εξαρτήσεις. Σύμφωνα με το HTTP Archive (2024), περίπου το 8% όλων των ιστοτόπων συνεχίζουν να χρησιμοποιούν Long Polling για βασική λειτουργικότητα πραγματικού χρόνου.
Long Polling και Short Polling λύνουν την ίδια εργασία — παράδοση δεδομένων από τον διακομιστή στον πελάτη — αλλά διαφέρουν θεμελιωδώς ως προς τον μηχανισμό και την αποδοτικότητα. Το Short Polling χρησιμοποιεί σταθερό διάστημα polling, όπου ο πελάτης στέλνει αιτήματα HTTP σε ίσα χρονικά διαστήματα ανεξάρτητα από το αν εμφανίστηκαν νέα δεδομένα στον διακομιστή.
| Χαρακτηριστικό | Long Polling | Short Polling |
|---|---|---|
| Εκκίνηση απάντησης | Διακομιστής στέλνει δεδομένα σε συμβάν | Διακομιστής απαντά σε κάθε αίτημα πελάτη |
| Καθυστέρηση παράδοσης | Ελάχιστη, έως 1 δευτερόλεπτο | Εξαρτάται από το διάστημα polling, 3-60 δευτερόλεπτα |
| Αριθμός αιτημάτων | 1 αίτημα ανά συμβάν ή timeout | N αιτήματα ανά μονάδα χρόνου (σταθερό) |
| Κίνηση σε αδράνεια | Χαμηλή (ένα ανοιχτό αίτημα) | Υψηλή (αιτήματα κάθε N δευτερόλεπτα) |
| Φορτίο διακομιστή | Διατήρηση συνδέσεων | Επεξεργασία συχνών αιτημάτων |
| Πολυπλοκότητα υλοποίησης | Μέτρια (ασύγχρονη επεξεργασία) | Χαμηλή (συνήθη αιτήματα HTTP) |
Short Polling είναι απλούστερο στην υλοποίηση, αλλά δημιουργεί σημαντικά μεγαλύτερο φορτίο στον διακομιστή και το δίκτυο με την ίδια συχνότητα ενημέρωσης δεδομένων. Εάν απαιτείται καθυστέρηση μικρότερη από 5 δευτερόλεπτα, το Short Polling δημιουργεί δεκάδες αιτήματα ανά λεπτό, ενώ το Long Polling χρησιμοποιεί ένα αίτημα ανά συμβάν ή timeout. Για εφαρμογές με σπάνια συμβάντα, το Long Polling είναι κατά τάξη μεγέθους πιο αποδοτικό σε κίνηση.
WebSocket είναι ένα πλήρες αμφίδρομο πρωτόκολλο πραγματικού χρόνου που λειτουργεί μέσω TCP μετά από αρχική χειραψία HTTP. Σε αντίθεση με το Long Polling, το WebSocket δημιουργεί μια μόνιμη σύνδεση και επιτρέπει στον διακομιστή να στέλνει δεδομένα στον πελάτη οποιαδήποτε στιγμή χωρίς να δημιουργεί νέο αίτημα HTTP.
Η επιλογή μεταξύ Long Polling και WebSocket εξαρτάται από διάφορους παράγοντες. Συμβατότητα: το Long Polling λειτουργεί μέσω όλων των proxy και τειχών προστασίας, το WebSocket μπορεί να μπλοκαριστεί από εταιρικά δίκτυα. Απόδοση: το WebSocket έχει μικρότερο overhead (2 byte ανά πλαίσιο έναντι πλήρων κεφαλίδων HTTP), που είναι κρίσιμο σε υψηλή συχνότητα μηνυμάτων. Κλιμάκωση: το Long Polling απαιτεί περισσότερους πόρους από την πλευρά του διακομιστή λόγω διατήρησης πολλαπλών συνδέσεων, το WebSocket χρησιμοποιεί σταθερή σύνδεση ανά συνεδρία.
Σύμφωνα με το Mozilla Developer Network (2024), το WebSocket υποστηρίζεται από όλα τα σύγχρονα προγράμματα περιήγησης από τις εκδόσεις 2011-2015, αλλά τα εταιρικά proxy (π.χ. Symantec Blue Coat) συνεχίζουν να το μπλοκάρουν στο 15-20% των εταιρικών δικτύων, γεγονός που διατηρεί τη σημασία του Long Polling ως λύσης fallback.
Συχνές Ερωτήσεις
Long Polling είναι όταν ο πελάτης ζητά από τον διακομιστή: “απάντησε όταν εμφανιστούν νέα δεδομένα”, και ο διακομιστής κρατά τη σύνδεση ανοιχτή, περιμένοντας ένα συμβάν. Μόλις εμφανιστούν τα δεδομένα, ο διακομιστής απαντά και ο πελάτης κάνει αμέσως την ίδια ερώτηση ξανά.
Στο Short Polling, ο πελάτης ρωτά τον διακομιστή κάθε N δευτερόλεπτα αν υπάρχουν δεδομένα, ακόμα κι αν δεν υπάρχουν. Στο Long Polling, ο πελάτης ρωτά μία φορά και ο διακομιστής απαντά μόνο όταν τα δεδομένα εμφανίζονται πραγματικά. Το Long Polling δημιουργεί λιγότερα κενά αιτήματα και μειώνει το φορτίο δικτύου.
Το Long Polling πρέπει να χρησιμοποιείται όταν το WebSocket δεν είναι διαθέσιμο: σε εταιρικά δίκτυα που μπλοκάρουν μη-HTTP πρωτόκολλα, όταν απαιτείται συμβατότητα προς τα πίσω με παλαιά προγράμματα περιήγησης ή υπάρχουν περιορισμοί από την πλευρά της φιλοξενίας. Το WebSocket είναι πιο αποδοτικό για ανταλλαγή δεδομένων υψηλής συχνότητας.
Το συνιστώμενο timeout Long Polling είναι 30-45 δευτερόλεπτα. Μικρότερη τιμή (10-15 δευτερόλεπτα) αυξάνει τον αριθμό αιτημάτων, μεγαλύτερη (60+ δευτερόλεπτα) είναι επικίνδυνη λόγω διακοπής σύνδεσης από ενδιάμεσα load balancer. Η τιμή timeout εξαρτάται από την αρχιτεκτονική δικτύου και τις απαιτήσεις καθυστέρησης.
Τα κύρια μειονεκτήματα του Long Polling — υψηλή κατανάλωση μνήμης στον διακομιστή κατά τη διατήρηση χιλιάδων συνδέσεων, δυσκολία οριζόντιας κλιμάκωσης (απαιτείται κεντρική ουρά συμβάντων) και έλλειψη πραγματικής αμφίδρομης επικοινωνίας — για αποστολή δεδομένων στον διακομιστή χρειάζονται ξεχωριστά αιτήματα POST.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης