Réseau et HTTP : partons en voyage en paquet

📖 15min read

Paix sur localhost et illusions brisées

Quand j’étais à l’école, mon monde entier était localhost. Même si j’installais quelque chose comme XAMPP et créais un tableau d’affichage en utilisant PHP, c’était un monde qui ne fonctionnait que sur mon ordinateur.

Lorsque j’ai rejoint l’entreprise, j’ai eu la chance d’être principalement responsable de la maintenance front-end. Il s’agissait d’une page d’administration basée sur Quasar (Vue.js), et la difficulté de la tâche n’était pas grande. Il ne me restait plus qu’à corriger la faute de frappe ou appeler l’API que mes seniors avaient déjà bien créée avec axios.get() et l’afficher à l’écran.

À cette époque, axios était comme une baguette magique pour moi. Même si je ne connais pas les principes compliqués, j’ai simplement saisi l’URL et les données ont été récupérées rapidement. J’ai aussi eu une pensée effrontée : « Il n’y a rien de spécial dans la communication entre le front-end et le back-end, n’est-ce pas ? »

Mais la paix n’a pas duré longtemps. En effet, j’étais un développeur full-stack « vivant » dans une petite et moyenne entreprise qui manquait de main-d’œuvre.

Bientôt, le moment est venu où j’ai dû créer ma propre API pour une nouvelle fonction, plutôt que de modifier l’écran. J’ai démarré un serveur en utilisant Spring Boot, que j’ai rapidement appris de YouTube, et j’ai envoyé une demande depuis le front-end. Cependant, tout ce qui apparaissait sur mon écran étaient des erreurs rouges CORS et des erreurs Timeout, pas des données.

« Cela a bien fonctionné lorsque je l’ai transmis en tant que variable locale, mais pourquoi ne puis-je pas simplement utiliser le réseau ? »

Déplacer la variable A vers la variable B sur mon ordinateur (Localhost) était une méthode sûre garantie à 100 %. Mais le monde en dehors du câble LAN était différent. C’était comme une intersection avec un feu de circulation cassé, et mes données étaient celles d’un camion circulant sur cette route dangereuse. Pendant tout ce temps, je chargeais simplement le camion et l’envoyais, mais je n’avais aucune idée de l’itinéraire emprunté par le camion ni de la manière dont il était divisé.

Dès que vos données quittent votre ordinateur, elles doivent emprunter des routes difficiles et sauvages.

Système de livraison dans un centre logistique numérique

Élargissons notre vision du monde du « centre logistique numérique ». Nous devons maintenant livrer les éléments (données) fabriqués dans notre usine (ordinateur) à des clients (serveurs) éloignés.

1. Paquet : Boîte d’expédition standard

Quelle que soit la taille des données que nous souhaitons envoyer (par exemple, une vidéo de 1 Go), elles ne peuvent pas être envoyées en une seule fois. C’est parce que les routes sont étroites et les camions sont petits. Nous découpons donc les données en très petits morceaux et les mettons dans des boîtes standardisées. Ceci est un « paquet ».

2. IP (Internet Protocol) : Adresse et navigation

Que puis-je faire si je n’ai qu’une boîte ? Vous devez savoir où aller.

3. TCP/UDP : différences dans les méthodes de livraison

Nous devons maintenant décider à quel camion envoyer les cartons.

Faut-il le donner avec certitude (TCP) ou le lancer rapidement (UDP) ?

[Vérification du code] Le vrai visage de HTTP n’est que le texte

Le HTTP que nous utilisons couramment n’est en réalité que le « contenu de la lettre » transporté sur un camion de livraison appelé TCP. Parlons au serveur Naver de la manière la plus primitive (Socket) sans navigateur ni bibliothèque. Vous verrez à quel point HTTP est simple, juste un morceau de texte.

import socket

# 1. Creer un socket TCP (decrocher le telephone)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. Se connecter au serveur Naver (223.130.195.200) sur le port 80 (composer le numero)
# L IP de Naver peut changer (a verifier avec nslookup [www.naver.com](https://www.naver.com))
target_host = "[www.naver.com](https://www.naver.com)"
target_port = 80
sock.connect((target_host, target_port))

# 3. Ecrire le message de requete HTTP (rediger ce que vous allez dire)
# Forme la plus brute d une requete HTTP
request = "GET / HTTP/1.1rnHost: [www.naver.com](https://www.naver.com)rnrn"

# 4. Envoyer (parler)
sock.send(request.encode())

# 5. Recevoir la reponse (ecouter)
response = sock.recv(4096)
print(response.decode())

# 6. Fermer la connexion (raccrocher)
sock.close()

Résultats de l’exécution (partiels) :

HTTP/1.1 200 OK
Server: NWS
Date: Mon, 01 Jan 2024 00:00:00 GMT
Content-Type: text/html; charset=UTF-8
...
<html>...</html>

Analyse : C’est tout ce qui se passe en interne lorsque nous appelons axios.get().

HTTP n’est pas une technologie spéciale, c’est juste une promesse faite d’« échanger des textes en utilisant ce protocole (protocole) lorsque nous communiquons ».

Compromis en pratique : fiabilité ou rapidité

Dans la pratique, notamment en développement back-end, il arrive un moment où il faut choisir entre TCP et UDP. (Bien sûr, la plupart utilisent HTTP basé sur TCP)

HTTP/3, qui est fréquemment posé dans les questions d’entretien récentes, est le produit de ce compromis. L’Internet que nous utilisons (HTTP/1.1, HTTP/2) fonctionne sur TCP. Parce que les données ne doivent jamais être détruites.

Mais les temps ont changé. Les gens veulent regarder des vidéos 4K sans interruption. Le processus de vérification méticuleux de TCP (Handshake) et les fonctionnalités telles que « Stand in line (Head of Line Blocking) » sont désormais devenus frustrants.

C’est ce que Google a pensé. « Hé, utilisons simplement UDP. Nous pouvons simplement régler le malaise au niveau de l’application. Il est important de l’envoyer rapidement ! »

Il s’agit du protocole QUIC et constitue la base de HTTP/3. Il s’agit d’une tendance de la technologie moderne qui a abandonné la stabilité inconditionnelle (TCP) et a choisi une vitesse écrasante (UDP), même si cela impliquait de prendre des risques.

Pour des vitesses plus rapides, nous modifions même le niveau de transport le plus bas (TCP -> UDP).

Fermeture : Imaginez une route invisible

Nous savons désormais comment les données sont divisées (paquets) et sur quel camion (TCP/UDP) elles voyagent.

Lorsqu’une requête API échoue sur le frontend, ne vous contentez pas de penser : « Le serveur est-il mort ? » comme avant. « Oh, la négociation à trois a-t-elle échoué ? Le paquet a-t-il été abandonné par le routeur au milieu ? Ou le DNS n’a-t-il pas trouvé l’adresse ? » Si vous pouvez imaginer une couche réseau comme celle-ci, vous n’êtes plus « un simple codeur »

Maintenant, les marchandises de notre usine sont arrivées en toute sécurité au client. Mais comment un client peut-il recevoir cet article, le déballer et l’afficher à l’écran ? Comment le code HTML que nous envoyons sera-t-il affiché dans le navigateur ?

La prochaine fois, nous parlerons de la destination finale du développement Web, les principes du rendu du navigateur.

Laisser un commentaire