Long Polling
Technique de communication client-serveur maintenant une connexion HTTP ouverte pour recevoir des mises à jour en temps quasi-réel sans polling répétitif.
Mis à jour le 26 janvier 2026
Le Long Polling est une technique de communication web qui améliore le polling classique en maintenant une connexion HTTP ouverte jusqu'à ce que le serveur ait de nouvelles données à transmettre. Contrairement au polling traditionnel qui effectue des requêtes répétitives à intervalles fixes, le long polling réduit la latence et la charge serveur en gardant la connexion active. Cette approche constitue une solution intermédiaire efficace entre le polling basique et les technologies temps réel modernes comme WebSockets.
Fondements du Long Polling
- Le client initie une requête HTTP qui reste ouverte côté serveur jusqu'à disponibilité de nouvelles données ou expiration d'un timeout
- Le serveur répond immédiatement quand des données sont disponibles, puis le client réinitie instantanément une nouvelle connexion
- La connexion persistante élimine les délais d'attente entre requêtes tout en restant compatible avec l'infrastructure HTTP standard
- Un mécanisme de timeout prévient les connexions indéfiniment suspendues et permet la gestion des erreurs réseau
Avantages du Long Polling
- Latence réduite comparée au polling classique grâce à la transmission immédiate des données disponibles
- Compatibilité universelle avec tous les proxies, firewalls et infrastructures HTTP existantes sans configuration spéciale
- Réduction significative de la charge serveur et de la bande passante en éliminant les requêtes inutiles à vide
- Implémentation simple ne nécessitant pas de protocoles ou bibliothèques spécialisées complexes
- Fallback idéal pour les environnements où WebSockets n'est pas supporté ou bloqué par des politiques réseau
Exemple concret
Voici une implémentation TypeScript complète d'un système de long polling pour un système de notifications :
class LongPollingClient {
private baseUrl: string;
private isPolling: boolean = false;
private abortController: AbortController | null = null;
constructor(baseUrl: string) {
this.baseUrl = baseUrl;
}
async startPolling(onMessage: (data: any) => void): Promise<void> {
this.isPolling = true;
while (this.isPolling) {
try {
this.abortController = new AbortController();
const response = await fetch(`${this.baseUrl}/poll`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
signal: this.abortController.signal,
});
if (response.ok) {
const data = await response.json();
onMessage(data);
}
// Reconnexion immédiate après réception
if (this.isPolling) {
continue;
}
} catch (error) {
if (error.name === 'AbortError') {
console.log('Polling arrêté');
break;
}
// Attente avant retry en cas d'erreur
await new Promise(resolve => setTimeout(resolve, 3000));
}
}
}
stopPolling(): void {
this.isPolling = false;
this.abortController?.abort();
}
}
// Côté serveur (Express/Node.js)
app.get('/poll', async (req, res) => {
const timeout = 30000; // 30 secondes
const checkInterval = 1000; // Vérification chaque seconde
const startTime = Date.now();
const checkForUpdates = async (): Promise<any | null> => {
// Logique métier pour vérifier nouvelles données
const updates = await db.getNewNotifications(req.user.id);
return updates.length > 0 ? updates : null;
};
const pollInterval = setInterval(async () => {
const updates = await checkForUpdates();
if (updates) {
clearInterval(pollInterval);
res.json({ success: true, data: updates });
} else if (Date.now() - startTime > timeout) {
clearInterval(pollInterval);
res.json({ success: true, data: [] }); // Timeout sans données
}
}, checkInterval);
// Nettoyage si client déconnecte
req.on('close', () => clearInterval(pollInterval));
});Mise en œuvre efficace
- Définir un timeout serveur approprié (20-60 secondes) équilibrant réactivité et charge serveur
- Implémenter une gestion robuste des erreurs avec retry exponentiel pour gérer les interruptions réseau
- Ajouter un mécanisme d'authentification et de session pour sécuriser les connexions longue durée
- Configurer les timeouts de proxy et load balancers pour supporter des connexions prolongées
- Monitorer le nombre de connexions simultanées pour éviter l'épuisement des ressources serveur
- Implémenter un système de heartbeat pour détecter les connexions mortes et libérer les ressources
- Prévoir une stratégie de fallback vers polling classique en cas de contraintes d'infrastructure
Conseil d'optimisation
Pour des applications à forte charge, combinez long polling avec une architecture pub/sub (Redis, RabbitMQ) côté serveur. Le serveur écoute les événements du message broker et répond immédiatement aux requêtes en attente, évitant le polling actif de la base de données et améliorant drastiquement la scalabilité à plusieurs milliers de connexions simultanées.
Outils et bibliothèques associés
- Socket.IO : bibliothèque proposant long polling comme transport fallback automatique avec WebSockets
- Nginx et HAProxy : reverse proxies configurables pour supporter efficacement les connexions longue durée
- Server-Sent Events (SSE) : alternative standardisée pour flux unidirectionnel serveur vers client
- Polling.js : librairie JavaScript légère spécialisée dans l'implémentation de patterns de polling avancés
- Redis Pub/Sub : système de messagerie pour coordonner les événements entre instances serveur en architecture distribuée
Le long polling reste une solution pragmatique pour implémenter des fonctionnalités temps quasi-réel sans complexité architecturale excessive. Sa compatibilité universelle et sa simplicité d'implémentation en font un choix stratégique pour des applications nécessitant des mises à jour push sans justifier l'infrastructure WebSocket complète, particulièrement dans des environnements réseau contraints ou pour des systèmes de notifications à fréquence modérée.
