
Gestion des utilisateurs et des messages
Implémentez la logique serveur essentielle pour votre chat Node.js : recevoir les messages des clients et les diffuser à tous les utilisateurs connectés avec Socket.IO.
Animer le chat : la logique serveur d'échange de messages
Nous avons maintenant un serveur Node.js qui accepte les connexions WebSocket via Socket.IO et un client frontend capable de se connecter et d'envoyer des messages. Cependant, pour l'instant, les messages envoyés par un client n'atteignent pas les autres. L'étape cruciale suivante est d'implémenter la logique côté serveur pour recevoir ces messages et les diffuser à tous les participants du chat.
C'est le coeur de l'application de chat : la capacité du serveur à agir comme un relais central, recevant une information d'un client et la propageant instantanément à tous les autres. Nous allons modifier notre gestionnaire d'événements `connection` sur le serveur pour écouter l'événement `chat message` émis par les clients et utiliser les capacités de diffusion de Socket.IO.
Nous aborderons également une gestion très basique des utilisateurs (simplement pour savoir qui envoie quoi), bien que nous n'implémentions pas d'authentification complète dans ce projet.
Recevoir et diffuser les messages (`broadcast`)
Reprenons notre fichier `server.js`. A l'intérieur du callback `io.on('connection', (socket) => { ... })`, nous devons ajouter un écouteur pour l'événement personnalisé `chat message` que notre client émet lorsqu'il envoie un message.
Quand le serveur reçoit un événement `chat message` d'un `socket` spécifique, il contient le message envoyé par ce client. La tâche du serveur est alors de prendre ce message et de l'envoyer à tous les clients actuellement connectés. Socket.IO rend cela très simple grâce à la méthode `io.emit(nom_evenement, donnees)` sur l'objet `io` principal. Utiliser `io.emit` envoie l'événement à toutes les sockets connectées, y compris celle qui a envoyé le message initial.
Modifions notre `server.js` pour inclure cette logique :
// server.js (extrait dans io.on('connection', ...))
io.on('connection', (socket) => {
console.log('Un utilisateur s\'est connecté:', socket.id);
// Ecouter l'événement 'chat message' venant de CE client spécifique
socket.on('chat message', (msg) => {
console.log(`Message reçu de ${socket.id}: ${msg}`);
// Diffuser (broadcast) le message à TOUS les clients connectés (y compris l'expéditeur)
// On émet le même événement 'chat message' que le client écoute
io.emit('chat message', msg);
});
socket.on('disconnect', () => {
console.log('Utilisateur déconnecté:', socket.id);
// Ici, plus tard, on pourrait notifier les autres utilisateurs
});
});Avec cet ajout, chaque fois qu'un client envoie un `chat message` via `socket.emit` dans `client.js`, le serveur le reçoit via `socket.on`, l'affiche dans sa console, puis le rediffuse immédiatement à tous les clients via `io.emit`. Les clients, qui écoutent cet événement `chat message` via `socket.on` dans `client.js`, recevront le message et l'afficheront.
Note : Si vous vouliez envoyer un message à tous les clients sauf à celui qui a émis l'événement initial (par exemple, pour une notification "Untel a rejoint le chat"), vous utiliseriez `socket.broadcast.emit('nom_evenement', donnees)`.
Gestion basique des utilisateurs (Pseudonymes)
Actuellement, les messages sont diffusés mais nous ne savons pas qui les a envoyés. Ajoutons une fonctionnalité très simple pour associer un pseudonyme à chaque connexion.
Côté Client (`client.js`) : Demandons un pseudo au chargement et envoyons-le au serveur.
// client.js (ajout au début)
const username = prompt("Quel est votre pseudonyme ?") || "Anonyme";
// Informer le serveur du pseudonyme (nouvel événement personnalisé)
socket.emit('set username', username);
// ... (reste du code client)
// Modifier l'affichage pour inclure le pseudo (si le serveur le renvoie)
socket.on('chat message', function(data) { // Supposons que le serveur envoie un objet {user, msg}
const item = document.createElement('li');
item.textContent = `${data.user}: ${data.msg}`; // Afficher "User: Message"
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
Côté Serveur (`server.js`) : Stockons le pseudo et utilisons-le lors de la diffusion.
// server.js (modifications dans io.on('connection', ...))
// Stockage très basique des pseudos (Perdu si le serveur redémarre !)
const users = {};
io.on('connection', (socket) => {
console.log('Un utilisateur s\'est connecté:', socket.id);
// Ecouter l'événement pour définir le pseudo
socket.on('set username', (username) => {
users[socket.id] = username || 'Anonyme';
console.log(`${socket.id} a choisi le pseudo: ${users[socket.id]}`);
// Notifier les autres qu'un utilisateur a rejoint (optionnel)
socket.broadcast.emit('user joined', `${users[socket.id]} a rejoint le chat.`);
});
// Modifier l'écouteur 'chat message'
socket.on('chat message', (msg) => {
const user = users[socket.id] || 'Anonyme'; // Récupérer le pseudo
console.log(`Message de ${user} (${socket.id}): ${msg}`);
// Diffuser le message ET le pseudo
io.emit('chat message', { user: user, msg: msg });
});
socket.on('disconnect', () => {
const user = users[socket.id] || 'Anonyme';
console.log(`Utilisateur déconnecté: ${user} (${socket.id})`);
// Notifier les autres (optionnel)
socket.broadcast.emit('user left', `${user} a quitté le chat.`);
// Nettoyer le stockage
delete users[socket.id];
});
});Côté Client (`client.js`) : Ajoutons l'écoute des notifications système (optionnel).
// client.js (ajout)
function addSystemMessage(msg) {
const item = document.createElement('li');
item.style.fontStyle = 'italic'; // Style pour les messages système
item.style.color = 'gray';
item.textContent = msg;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
}
socket.on('user joined', addSystemMessage);
socket.on('user left', addSystemMessage);
Important : Cette gestion des utilisateurs est très basique et uniquement en mémoire. Pour une application réelle, il faudrait utiliser une base de données ou un autre système de stockage persistant et un système d'authentification plus sécurisé.
Tester l'application de chat complète
Avec ces modifications côté serveur et client :
- Redémarrez votre serveur Node.js (`npm run dev`).
- Rechargez la page `index.html` (ou naviguez vers `http://localhost:3001` si servi par Express) dans deux ou plusieurs onglets/fenêtres de navigateur.
- Chaque nouvelle fenêtre devrait vous demander un pseudonyme.
- Envoyez des messages depuis différentes fenêtres.
- Vérifiez que les messages apparaissent dans toutes les fenêtres, préfixés par le bon pseudonyme.
- Vérifiez que les messages de connexion/déconnexion (si implémentés) s'affichent correctement pour les autres utilisateurs.
- Consultez les logs du serveur Node.js pour suivre les événements.
Vous disposez maintenant d'une application de chat temps réel fonctionnelle, démontrant la puissance de Node.js et Socket.IO pour la communication bidirectionnelle. La prochaine étape consisterait à déployer cette application sur un serveur cloud pour la rendre accessible publiquement.