📖 1. Introduction aux WebSockets
Les WebSockets permettent une communication bidirectionnelle en temps réel entre le navigateur et le serveur, via une connexion persistante.
❌ HTTP classique
- Requête → Réponse (cycle fermé)
- Communication unidirectionnelle client → serveur
- Nouvelle connexion à chaque requête
- Latence élevée pour le temps réel
✅ WebSocket
- Connexion persistante ouverte
- Bidirectionnel (client ↔ serveur)
- Faible latence (temps réel)
- Idéal pour chats, jeux, trading
Temps réel
Communication instantanée
Bidirectionnel
Client ↔ Serveur
Faible latence
Idéal pour applications interactives
Léger
En-têtes réduits après handshake
Client (Navigateur) Serveur
| |
|------- Handshake HTTP --------> |
|<------ Upgrade to WebSocket -----|
| |
|<======= Message WebSocket =======>|
|<======= Message WebSocket =======>|
|-------- Message WebSocket -----> |
| |
🏷️ 2. WebSocket Attributes
readyState
État de la connexion (0-3)
bufferedAmount
Nombre d'octets en attente d'envoi
protocol
Protocole utilisé (sous-protocole)
url
URL du serveur WebSocket
📌 Valeurs de readyState
const socket = new WebSocket('wss://echo.websocket.org');
console.log(socket.readyState); // 0 (CONNECTING)
socket.onopen = function() {
console.log(socket.readyState); // 1 (OPEN)
console.log(socket.url); // 'wss://echo.websocket.org'
};
📡 3. WebSocket Events
onopen
Déclenché quand la connexion est établie
onmessage
Déclenché à chaque réception de message
onerror
Déclenché en cas d'erreur
onclose
Déclenché quand la connexion est fermée
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = function(event) {
console.log('✅ Connexion établie');
socket.send('Hello WebSocket !');
};
socket.onmessage = function(event) {
console.log('📨 Message reçu:', event.data);
};
socket.onerror = function(error) {
console.error('❌ Erreur:', error);
};
socket.onclose = function(event) {
console.log('🔌 Déconnecté. Code:', event.code);
};
🛠️ 4. WebSocket Methods
send(data)
Envoie un message au serveur
socket.send(JSON.stringify({msg: 'Hello'}));
close(code, reason)
Ferme la connexion
📌 Codes de fermeture standards
- 1000 – Fermeture normale
- 1001 – Page fermée (navigateur)
- 1006 – Perte de connexion anormale
- 1011 – Erreur serveur
// Envoyer différents types de messages
socket.send('Message texte');
socket.send(JSON.stringify({ type: 'chat', message: 'Bonjour' }));
socket.send(new Blob(['Données binaires']));
socket.send(new ArrayBuffer(8));
// Fermer la connexion proprement
socket.close(1000, 'Déconnexion volontaire');
💻 5. Client Side HTML & JavaScript Code
<!DOCTYPE html>
<html>
<head>
<title>Client WebSocket</title>
<style>
#messages { height: 300px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; margin-bottom: 10px; }
.message { margin: 5px 0; }
.received { color: #2c3e66; }
.sent { color: #16a34a; text-align: right; }
</style>
</head>
<body>
<h2>🔌 Chat WebSocket</h2>
<div id="messages"></div>
<div>
<input type="text" id="messageInput" placeholder="Votre message..." style="width: 80%; padding: 8px;">
<button id="sendBtn">Envoyer</button>
</div>
<div id="status">🟡 Connexion en cours...</div>
<script>
const socket = new WebSocket('wss://echo.websocket.org');
const messagesDiv = document.getElementById('messages');
const statusDiv = document.getElementById('status');
function addMessage(text, type) {
const div = document.createElement('div');
div.className = `message ${type}`;
div.textContent = text;
messagesDiv.appendChild(div);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
socket.onopen = () => {
statusDiv.textContent = '🟢 Connecté au serveur WebSocket';
statusDiv.style.color = '#16a34a';
addMessage('✅ Connecté au serveur', 'received');
};
socket.onmessage = (event) => {
addMessage(`📨 Serveur: ${event.data}`, 'received');
};
socket.onerror = () => {
statusDiv.textContent = '🔴 Erreur de connexion';
statusDiv.style.color = '#dc2626';
};
socket.onclose = () => {
statusDiv.textContent = '⚪ Déconnecté';
statusDiv.style.color = '#666';
};
document.getElementById('sendBtn').onclick = () => {
const input = document.getElementById('messageInput');
const msg = input.value.trim();
if (msg && socket.readyState === WebSocket.OPEN) {
socket.send(msg);
addMessage(`📤 Moi: ${msg}`, 'sent');
input.value = '';
}
};
document.getElementById('messageInput').onkeypress = (e) => {
if (e.key === 'Enter') document.getElementById('sendBtn').click();
};
</script>
</body>
</html>
📝 Démo : Client WebSocket (serveur echo)
🖥️ 6. Server Side Code (exemple Node.js)
// serveur.js - Exemple avec Node.js et ws
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
console.log('Serveur WebSocket démarré sur ws://localhost:8080');
server.on('connection', (socket, request) => {
console.log('✅ Nouveau client connecté');
// Envoyer un message de bienvenue
socket.send('Bienvenue sur le serveur WebSocket !');
// Réception de message
socket.on('message', (data) => {
console.log(`Message reçu: ${data}`);
// Diffuser à tous les clients connectés
server.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(`Client: ${data}`);
}
});
});
// Déconnexion
socket.on('close', () => {
console.log('❌ Client déconnecté');
});
});
- Node.js + ws – Léger et performant
- Socket.io – Haut niveau, fallback automatique
- PHP + Ratchet – Pour PHP
- Python + websockets – Simple et efficace
- Java + Jetty – Pour applications Java
📝 7. WebSocket Example – Chat complet
<!DOCTYPE html>
<html>
<head>
<title>Chat WebSocket</title>
<style>
* { box-sizing: border-box; }
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background: #f5f5f5; }
.chat-container { background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); overflow: hidden; }
.chat-header { background: #2c3e66; color: white; padding: 15px; text-align: center; }
.chat-messages { height: 400px; overflow-y: auto; padding: 15px; background: #fafafa; }
.message { margin-bottom: 15px; display: flex; }
.message.me { justify-content: flex-end; }
.message-bubble { max-width: 70%; padding: 10px 15px; border-radius: 18px; }
.message.me .message-bubble { background: #3498db; color: white; }
.message.other .message-bubble { background: #e9ecef; color: #333; }
.message-time { font-size: 0.7em; margin-top: 5px; text-align: right; color: #999; }
.chat-input { display: flex; padding: 15px; background: white; border-top: 1px solid #ddd; }
.chat-input input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 25px; outline: none; }
.chat-input button { margin-left: 10px; padding: 10px 20px; background: #2c3e66; color: white; border: none; border-radius: 25px; cursor: pointer; }
.status { padding: 8px; text-align: center; font-size: 0.8em; background: #f8f9fa; }
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h2>💬 Chat WebSocket</h2>
</div>
<div class="chat-messages" id="messages"></div>
<div class="chat-input">
<input type="text" id="messageInput" placeholder="Votre message...">
<button id="sendBtn">Envoyer</button>
</div>
<div class="status" id="status">🟡 Connexion en cours...</div>
</div>
<script>
const socket = new WebSocket('wss://echo.websocket.org');
const messagesDiv = document.getElementById('messages');
const statusDiv = document.getElementById('status');
let username = 'Utilisateur_' + Math.floor(Math.random() * 1000);
function addMessage(text, type, isMe = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isMe ? 'me' : 'other'}`;
messageDiv.innerHTML = `
<div class="message-bubble">
<div>${text}</div>
<div class="message-time">${new Date().toLocaleTimeString()}</div>
</div>
`;
messagesDiv.appendChild(messageDiv);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
socket.onopen = () => {
statusDiv.innerHTML = '🟢 Connecté - Vous pouvez envoyer des messages';
statusDiv.style.background = '#d4edda';
addMessage('✅ Connecté au serveur WebSocket', 'system');
};
socket.onmessage = (event) => {
addMessage(event.data, 'received');
};
socket.onerror = () => {
statusDiv.innerHTML = '🔴 Erreur de connexion';
statusDiv.style.background = '#f8d7da';
};
socket.onclose = () => {
statusDiv.innerHTML = '⚪ Déconnecté';
statusDiv.style.background = '#e9ecef';
};
document.getElementById('sendBtn').onclick = () => {
const input = document.getElementById('messageInput');
const msg = input.value.trim();
if (msg && socket.readyState === WebSocket.OPEN) {
socket.send(msg);
addMessage(msg, 'sent', true);
input.value = '';
}
};
document.getElementById('messageInput').onkeypress = (e) => {
if (e.key === 'Enter') document.getElementById('sendBtn').click();
};
</script>
</body>
</html>
📝 Démo : Chat WebSocket complet
📝 Tableau récapitulatif
| Événement/Méthode | Description | Utilisation |
|---|---|---|
| Événements | onopen |
Connexion établie |
onmessage |
Message reçu | |
onerror |
Erreur | |
onclose |
Connexion fermée | |
| Méthodes | send(data) |
Envoyer un message |
close(code, reason) |
Fermer la connexion | |
| Attributs | readyState |
État (0-3) |
bufferedAmount |
Données en attente | |
protocol |
Protocole utilisé | |
url |
URL du serveur |
📌 Quiz de vérification
Question 1 : Quelle est la différence principale entre WebSocket et SSE ?
WebSocket est bidirectionnel (client ↔ serveur), SSE est unidirectionnel (serveur → client). WebSocket permet au client d'envoyer des messages au serveur.
Question 2 : Comment créer une connexion WebSocket côté client ?
const socket = new WebSocket('ws://serveur:port'); ou wss:// pour sécurisé.
Question 3 : Que signifie la valeur readyState = 1 ?
La connexion est ouverte (OPEN) et la communication est possible.
Question 4 : Quelle méthode permet d'envoyer un message au serveur ?
socket.send('message');
Question 5 : Que se passe-t-il si le serveur WebSocket n'est pas disponible ?
L'événement onerror est déclenché, puis onclose après échec de connexion.