iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
Node.js / HTML · Débutant

WebSocket

Comprendre le protocole WebSocket de zéro et construire un système de chat complet : connexion, utilisateurs en mémoire, messages privés et groupes — sans base de données.

Node.jswsJavaScriptHTML
01Le protocole WebSocket02Premier serveur WebSocket03Gérer les utilisateurs en mémoire04Chat global et broadcast05Messages privés06Groupes et rooms07Interface client complète
Chapitre 4·20 min

Chat global et broadcast

Le chat global est le cas le plus simple : un message envoyé par un utilisateur est diffusé à tous les autres connectés. C'est le broadcast pur.

Le type de message chat

On ajoute un case dans handleMessage :

server.js
case 'chat':
  handleChat(socket, msg)
  break
server.js
function handleChat(socket, msg) {
  const content = (msg.content || '').trim()
 
  if (!content) return
 
  const message = {
    type: 'chat',
    from: socket.username,
    content,
    at: new Date().toISOString(),
  }
 
  // Diffuser à tous — y compris l'expéditeur pour confirmer l'envoi
  broadcast(message)
}

L'expéditeur reçoit aussi le message via le broadcast global — c'est la confirmation que le serveur l'a bien reçu et redistribué. Le client peut ainsi afficher ses propres messages dans l'interface de la même façon que ceux des autres.

Côté client

client.html
function sendChat(content) {
  ws.send(JSON.stringify({ type: 'chat', content }))
}
 
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data)
 
  switch (msg.type) {
    case 'chat':
      console.log(`[${msg.at.slice(11, 19)}] ${msg.from} : ${msg.content}`)
      break
 
    case 'system':
      console.log(`--- ${msg.content} ---`)
      break
 
    case 'registered':
      console.log(msg.content)
      console.log('En ligne :', msg.users.join(', '))
      break
 
    case 'error':
      console.error('Erreur :', msg.content)
      break
  }
}

Tester le flux complet

Deux onglets, alice et bob inscrits.

Alice envoie :

ws.send(JSON.stringify({ type: 'chat', content: 'Bonjour tout le monde !' }))

Les deux onglets reçoivent :

[12:34:01] alice : Bonjour tout le monde !

Format de message standardisé

À ce stade, tous les messages serveur → client ont la même structure :

{
  type: string,    // 'chat' | 'system' | 'registered' | 'error' | 'list' | ...
  from?: string,   // username de l'expéditeur (si applicable)
  content: string, // contenu lisible
  at?: string,     // timestamp ISO (si applicable)
}

Garder cette cohérence facilite le traitement côté client — un seul switch (msg.type) couvre tout.

Ajouter une limite de longueur

Sans validation, un client peut envoyer un message de 10 Mo. Simple à bloquer :

server.js
function handleChat(socket, msg) {
  const content = (msg.content || '').trim()
 
  if (!content) return
  if (content.length > 500) {
    socket.send(JSON.stringify({ type: 'error', content: 'Message trop long (500 caractères max)' }))
    return
  }
 
  broadcast({
    type: 'chat',
    from: socket.username,
    content,
    at: new Date().toISOString(),
  })
}

Historique en mémoire (optionnel)

Si on veut envoyer les derniers messages aux nouveaux arrivants :

server.js
const history = [] // tableau des N derniers messages
 
function handleChat(socket, msg) {
  const content = (msg.content || '').trim()
  if (!content || content.length > 500) return
 
  const message = {
    type: 'chat',
    from: socket.username,
    content,
    at: new Date().toISOString(),
  }
 
  history.push(message)
  if (history.length > 50) history.shift() // garder les 50 derniers
 
  broadcast(message)
}

Et dans registerUser, après l'inscription :

// Envoyer l'historique au nouveau connecté
history.forEach((m) => socket.send(JSON.stringify(m)))

Le nouvel utilisateur voit les 50 derniers messages dès sa connexion — sans base de données.


Le broadcast global fonctionne. Chapitre suivant : messages privés, envoyés à un seul destinataire.

Précédent
Gérer les utilisateurs en mémoire
Suivant
Messages privés

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main