Quand un site « vivant » nécessite du code vivant
\nImaginez : vous écrivez un messager en TypeScript. Un utilisateur envoie un message — et l'interlocuteur doit le voir instantanément, sans recharger la page. Ou un tableau de bord boursier où le prix des actions change chaque seconde. Ou simplement un fil de notifications qui se met à jour tout seul. Comment implémenter cela ? Deux principaux candidats — long polling et WebSocket. Mais lequel choisir pour ne pas ruiner les performances et ne pas casser l'UX ?
\nDans cet article, avec des exemples concrets en TypeScript, nous analyserons comment fonctionne chaque technologie, où elles brillent et où elles déçoivent. Vous obtiendrez non seulement de la théorie, mais aussi des morceaux de code prêts à l'emploi pour Node.js et le navigateur. C'est parti !
\n\nQu'est-ce que le Long Polling en TypeScript et comment ça fonctionne
\nLe long polling est une évolution de la requête HTTP classique. Le client envoie une requête au serveur, mais le serveur ne répond pas immédiatement s'il n'y a pas de données. Il maintient la connexion ouverte jusqu'à ce qu'un nouvel événement se produise. Dès que les données sont prêtes — le serveur envoie la réponse, le client la traite et crée immédiatement une nouvelle requête. Le cycle se répète.
\nCela ressemble à une rustine ? En partie oui. Mais cela fonctionne même à travers les proxies d'entreprise les plus stricts qui bloquent WebSocket.
\n\nImplémentation du Long Polling en TypeScript (partie serveur)
\nÉcrivons un serveur simple avec Express en TypeScript. Il simulera une file d'attente de messages.
\nimport express, { Request, Response } from 'express';\nimport cors from 'cors';\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\n// Stockage des messages (simulation de file d'attente)\nconst messages: string[] = [];\n\n// Endpoint pour le long polling\napp.get('/poll', (req: Request, res: Response) => {\n // Attendre un nouveau message jusqu'à 30 secondes\n const checkForMessage = () => {\n if (messages.length > 0) {\n // Envoyer le premier message et le supprimer de la file\n const message = messages.shift();\n res.json({ data: message, timestamp: Date.now() });\n } else {\n // Si aucun message — continuer à attendre\n setTimeout(checkForMessage, 1000); // vérifier chaque seconde\n }\n };\n\n // Timeout au cas où il n'y a pas de message pendant longtemps\n const timeout = setTimeout(() => {\n res.json({ data: null, timeout: true });\n }, 30000);\n\n // Si le client se déconnecte — nettoyer les timers\n req.on('close', () => {\n clearTimeout(timeout);\n });\n\n checkForMessage();\n});\n\n// Endpoint pour envoyer un message\napp.post('/send', (req: Request, res: Response) => {\n const { message } = req.body;\n if (message) {\n messages.push(message);\n res.status(200).json({ status: 'ok' });\n } else {\n res.status(400).json({ error: 'message is required' });\n }\n});\n\napp.listen(3000, () => console.log('Long poll server on port 3000'));\n\nPartie cliente en TypeScript (navigateur)
\nasync function startLongPolling() {\n try {\n const response = await fetch('http://localhost:3000/poll');\n const data = await response.json();\n\n if (data.data) {\n console.log('Nouveau message :', data.data);\n // Mettre à jour l'interface utilisateur\n updateUI(data.data);\n }\n\n // Lancer immédiatement un nouveau poll\n startLongPolling();\n } catch (error) {\n console.error('Erreur long polling :', error);\n // Attendre 2 secondes et réessayer\n setTimeout(startLongPolling, 2000);\n }\n}\n\nfunction updateUI(message: string) {\n // Votre code pour mettre à jour le DOM\n const container = document.getElementById('messages');\n if (container) {\n const item = document.createElement('li');\n item.textContent = message;\n container.appendChild(item);\n }\n}\n\n// Démarrer au chargement de la page\ndocument.addEventListener('DOMContentLoaded', startLongPolling);\nConclusion : le long polling est simple à implémenter et ne nécessite pas de protocoles spéciaux. Mais chaque requête implique des en-têtes HTTP, des cookies, des frais généraux. Avec 1000 clients simultanés