Skip to content
On this page

Socket.io

Le principe des web sockets
Le principe des web sockets

Websockets

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. L'étape 2 consiste à déployer l'application sur un serveur de type DigitalOcean, etc.

  • Bases de données: Firebase and Supabase
  • Web et contrôleurs midi
  • Autres solutions
  • Vue.js, Nuxt.js

Le contenu ci-dessous est une version réduite de la documentation officielle que vous pourrez trouver sur https://socket.io/get-started/chat

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.

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

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

package.json

package.json est un fichier que vous trouverez dans beaucoup de projets aujourd'hui. C'est le manifeste du projet. Il va reprendre les différentes dépendances du projet (dependencies), des commandes de build etc.. mais aussi les informations de base (nom, version, description). Ce sont celles-là que nous allons entrer maintenant. Dans ce fichier package.json, reprenez les infos ci-dessous (ou modifiez-les):

js
{
  "name": "Drawing together",
  "version": "0.1",
  "description": "Une application pour dessiner ensemble.",
  "dependencies": {}
}

A présent, nous pouvons installer l'un ou l'autre module en utilisant notre terminal. Commençons par installer Express.js, un framework nous permettant de créer très rapidement de petites applications web et de gérer le côté serveur.

Au lieu de npm, vous pouvez également utiliser Yarn. La syntaxe est très légèrement différente mais le principe reste le même.

js
npm install express

Vous devriez maintenant trouver Express dans les dépendances listées de votre package.json, et un répertoire node_modules dans le dossier de votre projet.

Une fois Express installé, nous pouvons créer le point d'entrée de notre serveur, par exemple index.js.

js
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);

app.get('/', (req, res) => {
  res.send('<h1>Bonjour les amis</h1>');
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});

Le code ci-dessus, une fois exécuté, lancera notre serveur web sur le port local 3000 et, si on accède à sa racine (/) enverra au navigateur le code HTML de la ligne 7.

Nous pouvons d'ores et déjà tester ceci en lançant la commande suivante dans notre terminal.

bash
node index.js

Pour que cela soit un peu plus pratique à l'avenir, plutôt que d'envoyer une chaîne de caractères HTML au navigateur, nous allons tout simplement lui envoyer le contenu d'un fichier HTML entier, en modifiant notre code à la ligne 6 comme ceci:

js
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

Bien évidemment, il nous faut créer ce fichier index.html. DOnnez-lui par exemple le contenu suivant:

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test Socket.io</title>
</head>
<body>
    <form id="form">
        <input id="input" type="text" />
        <button>Envoyer</button>
    </form>
</body>
</html>

Redémarrez votre serveur en tapant dans votre terminal Ctrl+C , puis node index.js à nouveau. Testez.

SASS (parenthèse)

Comme on a besoin de bien voir ce que l'on fait, on va un peu styler tout cela pour y voir plus clair. Et comme on aime faire les choses bien. On va installer SASS.

Et comme nous avons Node.js déjà installé sur notre machine, nous pouvons entrer la commande suivante pour installer SASS en global:

bash
npm install -g sass

Maintenant, nous pouvons, dans notre projet, créer un fichier styles.scss (par exemple)

scss
body {
    background:rgb(245, 208, 76);
    padding:2rem;  
}
form {
    display:flex;
    flex-direction: column;
    input, button {
        padding:1rem;
        margin-bottom:1rem;
        font-size:1.5rem;
        border:none;
    }
}

Et ajouter la ligne suivante à notre fichier HTML, qui chargera le fichier compilé.

html
<link rel="stylesheet" href="styles.css">

Pour surveiller le fichier scss et compiler automatiquement dès qu'il change, nous allons faire ceci:

bash
sass --watch styles.scss styles.css

Et pour mettre la page à jour dès qu'un fichier est modifié, nous pouvons utiliser Live server dans VSCode ou utiliser Nodemon. Je crois que c'est égal.

Dans tous les cas, il nous faudra:

  1. Lancer le serveur (et le surveiller)
  2. Lancer al commande watch pour SASS si on l'utilise.

Dans le vif du sujet: Socket.io

Intégrons maintenant socket.io à notre projet. La bibliothèque est composée de deux partie distinctes.

  1. La partie serveur qui intègre socket.io et tourne avec node.js
  2. La partie client composée du framework de votre choix ainsi que de la bibliothèque socket.io.js

Entrez la commande suivante pour l'installer.

bash
npm install socket.io

Ensuite, modifions le fichier index.js de notre serveur pour le connecter. On ajoute donc les lignes suivantes au niveau de la ligne 5 (plus ou moins):

js
const { Server } = require("socket.io");
const io = new Server(server);

Et les lignes suivantes après le bloc qui concerne le routing:

js
io.on('connection', (socket) => {
    console.log('Un utilisateur s\'est connecté');
});

Notre fichier index.js ressemble donc à ceci:

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

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
    console.log('Un utilisateur s\'est connecté');
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});

Il nous reste enfin à coller le code suivant avant la fermeture de notre body, dans notre fichier index.html:

html
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

TIP

Vous pouvez également utiliser un CDN à la place des fichiers locaux. (Voir ci-dessous). Aussi, nous ne spécifions aucun URL lorsqu'on appelle io() car on utilise par défaut l'hôte qui sert la page.

html
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>

Il a 3 choses à "faire tourner" pour l'instant, dont certaines facultatives:

  1. Le serveur
  2. La surveillance et compilation du fichier SCSS (facultatif)
  3. Le Hot reload pour que la page se recharge d'elle-même si on change quelque-chose (facultatif)

Chaque socket déclenche également un event chaque fois qu'un utilisateur se déconnecte. On peut donc ajouter ceci à notre fichier index.js

js
io.on('connection', (socket) => {
    console.log('Un utilisateur s\'est connecté');
    socket.on('disconnect', () => {
        console.log('Un utilisateur s\'est envolé');
    });
});

Émission

L'idée principale derrière Socket.IO est que vous pouvez envoyer et recevoir tous les événements que vous voulez, avec toutes les données que vous voulez. Tous les objets pouvant être encodés en JSON le feront, et les données binaires sont également prises en charge.

Faisons en sorte que lorsque l'utilisateur saisit un message, le serveur l'obtienne en tant qu'événement chat message. La section script dans notre fichier index.html devrait maintenant ressembler à ceci.

html
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
<script>
    var socket = io();

    var form = document.getElementById('form');
    var input = document.getElementById('input');

    form.addEventListener('submit', function(e) {
        e.preventDefault();
        if (input.value) {
            socket.emit('chat message', input.value);
            input.value = '';
        }
    });
</script>

Et nous modifions le code de l'index.js de façon à réceptionner ce message..

js
io.on('connection', (socket) => {
  console.log('Un utilisateur s\'est connecté');
  socket.on(
    'chat message', (msg) => {
      console.log('message: ' + msg);
    });
});

TIP

A ce stade, j'ai eu une erreur de connection refusée que j'ai résolue en chargeant socket.io à partir du CDN.

Afin maintenant d'envoyer ces messages aux autres utilisateurs, on va utiliser la fonction io.emit() de socket.io.

js
io.emit('some event', { someProperty: 'some value', otherProperty: 'other value' }); // This will emit the event to all connected sockets

Pour envoyer à tout le monde sauf au socket émetteur, on utilise le flag broadcast comme ceci :

js
io.on('connection', (socket) => {
  socket.broadcast.emit('hi');
});

Réception

Il ne nous reste plus qu'à modifier le code côté client pour réceptionner ces messages dans la vue.

html
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();

  var messages = document.getElementById('messages');
  var form = document.getElementById('form');
  var input = document.getElementById('input');

  form.addEventListener('submit', function(e) {
    e.preventDefault();
    if (input.value) {
      socket.emit('chat message', input.value);
      input.value = '';
    }
  });

  socket.on('chat message', function(msg) {
    var item = document.createElement('li');
    item.textContent = msg;
    messages.appendChild(item);
    window.scrollTo(0, document.body.scrollHeight);
  });
</script>

En utilisant le même domaine, en local


SASS

  • creer le fichier html
  • créer styles.scss

Si SASS n'est pas encore installé sur le système

bash
npm install -g node-sass 
bash
npm init 

Dans l'objet scripts de package.json :

json
"scss": "node-sass --watch assets/scss -o assets/css"

Lancer la commande

bash
npm run scss //ou yarn scss

Maintenant que le HTML et SASS sont en places...

Installer vue

bash
npm install -g @vue/cli

Ajouter sudo devant la commande si nécessaire

https://www.youtube.com/watch?v=lcYn0tgUvHE

yarn serve