Skip to content

WebSockets 1

Principe d’un canal WebSocket bidirectionnel
Principe d’un canal WebSocket bidirectionnel

Objectif

Le but est de pouvoir connecter plusieurs machines d'un même réseau pour créer le même principe qu'un chat ou un outil de dessin collaboratif. Le principe pourra ensuite évoluer pour s'adapter à d'autres projets.

Chaque fois que le serveur recevra un message d'un client, il le répercutera sur tous les autres clients connectés.

Pré-requis

  • Node.js installé (>= 18 recommandé)
  • Deux ordinateurs connectés au même réseau local
  • Port 3000 disponible sur la machine serveur

Socket.io

Socket.io est une bibliothèque utilisant les websockets, une technologie créant un canal de communication bidirectionnel entre un client (des clients) et un serveur.


Étape 1 — Initialiser le projet

Créons donc un dossier (celui de notre projet). A ce stade, bien évidemment, nous devons avoir déjà installé Node et npm sur notre machine. Dans ce dossier, créons un fichier package.json (npm init)

Crée un dossier projet (sur l’ordinateur serveur, ex: MacBook Pro).

bash
mkdir monprojet && cd monprojet
npm init -y
npm install express socket.io

Étape 2 — Créer le serveur web

js
// server.js
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const { Server } = require('socket.io');

const io = new Server(http, {
  cors: { origin: '*' }
});

// On sert les fichiers du dossier "public"
app.use(express.static('public'));

// Quand un client se connecte
io.on('connection', (socket) => {
  console.log('Nouveau client connecté :', socket.id);

  // On écoute les messages venant de l'émetteur
  socket.on('messageFromSender', (data) => {
    console.log('Données reçues du sender :', data);

    // On renvoie à tous les autres clients (broadcast)
    socket.broadcast.emit('messageFromServer', data);
  });
});

// On démarre le serveur
const PORT = 3000;
http.listen(PORT, () => {
  console.log('Serveur sur http://localhost:' + PORT);
});

Étape 3 — La page web de l'émetteur (ordi 1)

Créer un dossier public et y créer le fichier emetteur.html (par exemple) :

html
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <title>Émetteur</title>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <script src="https://cdn.jsdelivr.net/npm/p5@1.9.0/lib/p5.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
  <script src="emetteur.js"></script>
</body>
</html>

Et y créer également le fichier emetteur.js :

js
let socket;

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(220);
  // Connexion au serveur socket.io (même adresse que la page)
  socket = io();
}

function draw() {
  if(mouseIsPressed) {
    const msg = {
      px: pmouseX,
      py: pmouseY,
      x: mouseX,
      y: mouseY,
      time: Date.now()
    };

    // On envoie au serveur
    socket.emit('messageFromSender', msg);
    console.log('Message envoyé :', msg);
  }
}

Étape 4 — La page du récepteur

html
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <title>Récepteur</title>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <script src="https://cdn.jsdelivr.net/npm/p5@1.9.0/lib/p5.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
  <script src="recepteur.js"></script>
</body>
</html>

Avec le script p5js pour la réception :

js
let socket;

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(0);

  socket = io();

  // Quand on reçoit un message du serveur
  socket.on('messageFromServer', (msg) => {
    console.log('Message reçu :', msg);
    stroke(255);
    line(msg.px, msg.py, msg.x, msg.y);
  });
}

function draw() {}

Styles CSS

Et une petite feuille de styles de base, commune aux deux pages (émettrice et réceptrice)

css
* {
    box-sizing: border-box;
}

body {
    margin:0;
    overflow: hidden;
}

Autres liens

Victoria

Concrètement, après avoir fait un npm install dans le projet (si Node.js et npm sont présents sur la machine, bien sûr), lancer la commande npm start. Cette commande, comme on peut le voir dans le fichier package.json (dans la partie scripts) va nous permettre de lancer le server.js (notre serveur web), d'attendre qu'il soit lancé, puis d'ouvrir la page localhost (port 3000) dans le navigateur.

Limitation importante

Il est important d'ouvrir la page localhost:3000/ordi2/micro.html dans Safari. Cela nous permet de contourner les limitations (vraiment bloquantes) des autres navigateurs. En effet, Apple utilise ses propres serveurs et ne nécessite pas de connexion sécurisée (HTTPS) pour la reconnaissance vocale. Néanmoins, comme pour les autres navigateurs, Safari ne lancera la reconnaissance vocale qu'après une action utilisateur (clic par exemple).

Il y a donc 3 pages, connectées, à ouvrir. L'une d'elles concerne uniquement la gestion du micro. On peut même imaginer qu'elle soit accessible sur un téléphone mobile (à partir d'un QR code par ex) si tant est que ce téléphone soit connecté au même réseau local (WiFi à priori). A tester..