Client et serveur web


Le protocole HTTP (HyperText Transfer Protocol)

C'est un protocole de communication client-serveur développé pour le World Wide Web.

Le but du protocole HTTP est de permettre un transfert de fichiers (essentiellement au format HTML) localisés grâce à une chaîne de caractères appelée URL entre un client (navigateur) et un serveur Web

Un serveur web est un logiciel capable de répondre à des requêtes HTTP, c'est à dire de renvoyer des données comme une page HTML en réponse à des demandes écrites en HTTP (exemple : une requête GET)


Communication entre client et serveur

  • Le serveur écoute le port. Il attend la connexion d'un client.
  • Tant qu'aucun client ne se présente, on reste bloqué (accept)
  • Le client envoie une requête.
  • Le serveur traite la requête puis envoie la réponse.




Serveur web, code HTML et MicroPython pour écrire une variable depuis une page Web, pilotage d'une LED



Commande une LED raccordée sur la broche GP20 depuis deux liens hypertexte.


Raccorder une LED sur la broche 20 (repère D20  Shield base Grove).

Connecter le Raspberry Pi Pico au routeur WIfi, pour cela créer un fichier connexion_wifi.py et le téléverser le sur la carte (voir chapitre Configuration Wifi)

Connecter le smartphone au routeur Wifi.


Le client envoie au serveur certains paramètres GET par le biais de l’URL demandée. Ces paramètres sont ajoutées à l’URL avec le signe « ? » et ils indiquent au serveur quelles ressources sont demandées.  Le nom et sa valeur sont toujours séparées avec le symbole « = ». La syntaxe retenue est la suivante : ?nom1=valeur1

Les paramètres étant transmis par l’URL, il est conseillé d'utiliser les paramètres GET seulement pour des applications qui ne posent pas de problème de sécurité.


Ce qui donne dans l'exemple suivant :  

    • /?led=on  ou /?led=off dans la requête du client ; 
    • En décodant la requête, le serveur saura s'il faut allumer ou non la LED grâce aux paramètres ;
    • Le serveur donnera comme réponse au client le code HTML contenu dans la fonction web_page() ;



import connexion_wifi
from machine import Pin
import socket


led1_pin = Pin(20, Pin.OUT)  # broche GP20 en sortie (repère D20 shield Grove)

def web_page():
    html = """<!DOCTYPE html>
    <html>
        <head 
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>Pico Serveur Web</title>
            <style>
                p { font-size: 36px; }
            </style>
        </head>
        <body>
            <h1>Commande LED</h1>
            <p><a href="/?led=on">Allumer LED</a></p>
            <P><a href="/?led=off">Eteindre LED</a></p>
        </body>
    </html>
    """
    return html



# Ouverture du socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)


print('Ecoute en fonctionnement\n', addr,"\n")



# Ecoute du port et attente connexion d'un client
while True:
    try:                       
        print("Attente connexion d'un client")
        connexionClient, adresse = s.accept()
        print("Connecté avec le client\n", adresse)

        print("Attente requete du client")
        requete = connexionClient.recv(1024)     #requête du client
        requete = str(requete)
        print("Requête du client = \n", requete,"\n")

        #analyse de la requête, recherche de led=on ou led=off
        if "GET /?led=on" in requete:
            led1_pin.value(1)
        if "GET /?led=off" in requete:
            led1_pin.value(0)

        print("Envoi reponse du serveur : code HTML a afficher")
        reponse = web_page()
        connexionClient.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        connexionClient.send(reponse)
        connexionClient.close()  
        print("Connexion avec le client fermée\n")
        
    except OSError as e:
        connexionClient.close()  
        print("Connexion avec le client fermée, le programme a déclenché une erreur\n")





Serveur web, code HTML pour afficher des boutons On OFF sur une page web


Le code MicroPython est identique au code avec liens hypertextes ci-dessus.



HTML


<html>
       <head>
               <title>Pico</title>
               <meta name="viewport" content="width=device-width, initial-scale=1">
               <style>
                       html
                       {
                               font-family: Helvetica;
                               margin: 0px auto;
                               text-align: center;
                       }
                       h1
                       {
                               color: #0F3376;
                               padding: 2vh;
                       }
                       p
                       {
                               font-size: 24px;
                       }
                       .button
                       {
                               background-color: #4CAF50;   /* Vert */
                               border: none;
                               border-radius: 6px;   /* Angle arrondi */
                               color: white;
                               padding: 15px 32px;
                               text-align: center;
                               text-decoration: none;
                               font-size: 30px;
                       }
                       .button2
                       {
                               background-color: #f44336; /* Rouge */
                       }
               </style>
       </head>
       <body>
               <h1>Pico Serveur Web</h1>
               <p><a href="/?led=on"><button class="button">ON</button></a></p>
               <p><a href="/?led=off"><button class="button button2">OFF</button></a></p>
       </body>
</html>




Code sur https://www.w3schools.com



Serveur web, code HTML et MicroPython pour afficher une variable sur une page web



Affiche le résultat de la conversion analogique numérique de la tension présente sur la broche 34


Raccorder un potentiomètre sur la broche ADC0 (repère A0 shield Grove)

Connecter le Raspberry Pi Pico au routeur WIfi, pour cela créer un fichier connexion_wifi.py et le téléverser le sur la carte (voir chapitre Configuration Wifi)

Connecter le smartphone au routeur Wifi.


La variable à afficher, ici pot, est directement intégrée au code HTML.


Pour éviter de rafraîchir manuellement la page, ajouter le code HTML suivant dans l'en-tête (head)  :  <meta http-equiv="refresh" content="1">

Le client enverra automatiquement toutes les secondes une requête GET pour rafraîchira la page.



import connexion_wifi
from machine import ADC, Pin
import socket


can = ADC(0)                # crée un objet ADC sur la broche ADC0


def web_page():
    pot = can.read_u16()
    print("CAN =", pot)
    html = """
    <!DOCTYPE html>
    <html>
        <head>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>Pico Serveur Web</title>
            <meta http-equiv="refresh" content="1">
            <style>
                p { font-size: 36px; }
            </style>
        </head>
        <body>
            <h1>CAN potentiomètre = </h1>
            <p><span>""" + str(pot) + """</span></p>
        </body>
    </html>
    """
    return html

# Ouverture du socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)


print('Ecoute en fonctionnement\n', addr,"\n")



# Ecoute du port et attente connexion d'un client
while True:
    try:                       
        print("Attente connexion d'un client")
        connexionClient, adresse = s.accept()
        print("Connecté avec le client\n", adresse)

        print("Attente requete du client")
        requete = connexionClient.recv(1024)     #requête du client
        requete = str(requete)
        print("Requête du client = \n", requete,"\n")

        print("Envoi reponse du serveur : code HTML a afficher")
        reponse = web_page()
        connexionClient.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        connexionClient.send(reponse)
        connexionClient.close()  
        print("Connexion avec le client fermée\n")
        
    except OSError as e:
        connexionClient.close()  
        print("Connexion avec le client fermée, le programme a déclenché une erreur\n")






Serveur web, code HTML et MicroPython pour afficher un potentiomètre sur une page web


Ce code permet d'afficher un potentiomètre sur le navigateur et de transmettre sa valeur courante par requête.


Le client envoie au serveur des  paramètres GET.

Dans l'exemple suivant :  

    • Le client envoie  /?pot1_valeur=121 par exemple. 121 étant la valeur courante du potentiomètre.
    • Le serveur décode la requête pour isoler la valeur courante : 121
    • Le serveur donnera comme réponse au client le code HTML contenu dans la fonction web_page() ;




import connexion_wifi
import socket



def web_page():
    html = """
    <!DOCTYPE html>
    <html>
        <head>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>Pico Serveur Web</title>
            <style>
                p { font-size: 36px; }
                .slidecontainer {width: 100%;}
                .slider {
                    -webkit-appearance: none;
                    width: 80%;
                    height: 25px;
                    background: #ffd800;    /*couleur glisssière jaune*/
                    outline: none;
                }
                .slider::-webkit-slider-thumb {
                    -webkit-appearance: none;
                    appearance: none;
                    width: 35px;
                    height: 35px;
                    background: #FF0000; /*couleur curseur rouge*/
                    cursor: pointer;
                }
            </style>
        </head>
        
        <body>
            <h1>Potentiometre 1</h1>
            <p><input type="range" onchange="fct_envoi()" min="0" max="255" value="127" class="slider" id="id_pot1" ></p>
            <p>Valeur : <span id="id_affichage_pot1_valeur"></span></p>
            
            <script>    // Java script
            function fct_envoi() {
                var pot1 = document.getElementById("id_pot1");
                var pot1_valeur = pot1.value;
                document.getElementById("id_affichage_pot1_valeur").innerHTML = pot1_valeur
                
                var objet_XHR = new XMLHttpRequest();
                objet_XHR.open("GET", "/pot1?valeur="+pot1_valeur, true);
                objet_XHR.send();
            }
            </script>
        </body>
    </html>
    """
    return html


# Ouverture du socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)


print('Ecoute en fonctionnement\n', addr,"\n")



# Ecoute du port et attente connexion d'un client
while True:
    try:                       
        print("Attente connexion d'un client")
        connexionClient, adresse = s.accept()
        print("Connecté avec le client\n", adresse)

        print("Attente requete du client")
        requete = connexionClient.recv(1024)     #requête du client
        requete = str(requete)
        print("Requête du client = \n", requete,"\n")

        #analyse de la requête, recherche de pot1?valeur=
        if "GET /pot1?valeur=" in requete:
            indice_debut = requete.find("=")+1
            indice_fin = requete.find("HTTP")-1
            pot1_valeur = int(requete[indice_debut:indice_fin])
            print("pot1_valeur = ", pot1_valeur, "\n")

        print("Envoi reponse du serveur : code HTML a afficher")
        reponse = web_page()
        connexionClient.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        connexionClient.send(reponse)
        connexionClient.close()  
        print("Connexion avec le client fermée\n")
        
    except OSError as e:
        connexionClient.close()  
        print("Connexion avec le client fermée, le programme a déclenché une erreur\n")






Code sur https://www.w3schools.com




























Créé avec HelpNDoc Personal Edition: Avantages d'un outil de création d'aide