PC SOFT

DOCUMENTATION EN LIGNE
DE WINDEVWEBDEV ET WINDEV MOBILE

  • Présentation
  • Fonctionnement
  • Exemple
  • Code de connexion au serveur et d'envoi de messages
  • Code de la procédure Callback de retour
  • Exemple de serveur de WebSockets développé en WINDEV
WINDEV
WindowsLinuxUniversal Windows 10 AppJavaEtats et RequêtesCode Utilisateur (MCU)
WEBDEV
WindowsLinuxPHPWEBDEV - Code Navigateur
WINDEV Mobile
AndroidWidget AndroidiPhone/iPadApple WatchUniversal Windows 10 AppWindows Mobile
Autres
Procédures stockées
Présentation
Les WebSockets permettent de communiquer depuis une application Web (site Intranet ou Internet exécuté dans un navigateur) vers un serveur Web en utilisant des sockets.
Remarque : Le serveur de WebSockets peut correspondre à une application WINDEV, WEBDEV ou autre. Cette page présente un exemple de serveur de WebSockets réalisé en WLangage avec WINDEV.
Fonctionnement
Pour envoyer un message depuis une application Web en utilisant les WebSockets, il est nécessaire de programmer les traitements suivants côté navigateur :
  • connexion au serveur,
  • envoi de message,
  • déconnexion.
Pour cela, vous disposez des mêmes fonctions WLangage que côté serveur :
SocketConnectePermet de se connecter au serveur de webSockets.
SocketEcritPermet d'envoyer un message au serveur de webSockets.
SocketExistePermet de vérifier si la socket servant à la connexion n'a pas déjà été créée.
SocketFermePermet de fermer la socket une fois les envois de messages terminés.
Exemple

Code de connexion au serveur et d'envoi de messages

SocketConnecte("client", "ws://<AdresseIPServeur>:5001", ProcRetour)

Info("fermeture socket...")

SocketFerme("client")

Code de la procédure Callback de retour

PROCEDURE ProcRetour(nEvenement, sMessage)
gsRes est une chaîne = ""

SELON nEvenement
CAS SocketOuverture :
SocketEcrit("client", "Texte du message envoyé depuis le navigateur.")
RETOUR
CAS SocketMessage : gsRes += [RC] + "Réception du message : " + sMessage

CAS SocketFermeture : gsRes += [RC] + "Fermeture de la socket"

CAS SocketErreur : gsRes += [RC] + "Erreur de la socket : " + sMessage
RETOUR
AUTRE CAS

FIN
Info(gsRes)
Exemple de serveur de WebSockets développé en WINDEV
Voici un exemple de code pour réaliser un serveur de WebSockets avec WINDEV. Ce code doit être adapté selon votre configuration et vos besoins (Adresse IP du serveur, ports à ouvrir, ...).
Avant de modifier cet exemple, il est nécessaire de connaître la technique et la théorie des WebSockets. Cet exemple n'a pas pour but d'expliquer le fonctionnement théorique des WebSockets. Il montre juste comment utiliser des WebSockets.
Pour créer un serveur de WebSockets en WINDEV :
  1. Créez un projet WINDEV.
  2. Créez une fenêtre vierge
  3. Créer une procédure locale pServeurSocketEcoute par exemple pour écouter les messages envoyés par le client depuis son site Web. Le code de cette procédure locale est le suivant :
    // Code de la procédure locale : Ecoute des messages envoyés par le client socket.

    PROCÉDURE pServeurSocketEcoute()

    ENTETE_WEBSOCKET_CLIENT est une chaîne = "Sec-WebSocket-Key: "
    ENTETE_WEBSOCKET_PROTOCOL est une chaîne = "Sec-WebSocket-Protocol: "

    // Création du serveur de sockets pour effectuer l'écoute des messages arrivants
    SI SocketCrée("Serveur", 5001) = Faux ALORS
    Erreur("Erreur de création " + ErreurInfo(errMessage))
    SINON
    // Process (ou thread) d'écoute des messages
    // Ce traitement est exécuté en tâche de fond
    // On écoute en permanence car on ne sait pas quand un message arrive
    ThreadExécute("Thread1", threadNormal, ProcédureAttente)
    FIN

    //-----------------------------------------------------------
    // Procédure appelée dans le thread d'écoute
    PROCÉDURE INTERNE ProcédureAttente()

    // Boucle sans fin afin d'attendre une connexion d'un client.
    // Dès qu'un client se connecte pour envoyer un message,
    // un thread est lancé afin de gérer les messages arrivants.
    // La procédure ProcédureGestion gère les messages arrivants.
    BOUCLE
    Multitâche(0)
    SI SocketAttendConnexion("Serveur") ALORS
    Canal est une chaîne
    Canal = SocketAccepte("Serveur")
    SocketChangeModeTransmission(Canal, SocketSansMarqueurFin)
    ThreadExécute(Canal, threadNormal, ProcédureGestion, Canal)
    FIN
    FIN

    //--------------------------------------------------------------
    // Code de la procédure de gestion des messages arrivants
    PROCÉDURE INTERNE ProcédureGestion(Canal)

    sRequête est une chaîne ANSI
    tabProtocol est un tableau de chaînes
    sRes est une chaîne
    sProtocol est une chaîne = "JSON"

    // Lecture de la socket jusqu'à avoir la séquence de terminaison d'un message
    // Dans notre cas, 2 RC qui se suivent
    TANTQUE ChaîneOccurrence(sRequête, RC + RC) = 0
    sRequête += SocketLit(Canal)
    FIN

    // Traitement de la requête qui arrive
    // La variable sRequête contient le message à traiter
    // On analyse la chaîne
    sClé est une chaîne ANSI
    POUR TOUTE CHAÎNE sLigne DE sRequête SEPAREE PAR RC
    Trace(sLigne)
    SI sLigne [=  ENTETE_WEBSOCKET_CLIENT ALORS
    sClé = sLigne[[Taille(ENTETE_WEBSOCKET_CLIENT)+1 A]]
    SINON SI sLigne [= ENTETE_WEBSOCKET_PROTOCOL
    // Récupération des protocoles
    ChaîneVersTableau(ExtraitChaîne(sLigne, 2, ":"), tabProtocol, ",")
    FIN
    FIN


    // Préparation de la réponse à envoyer au client
    sRes = [
    HTTP/1.1 101 Web Socket Protocol Handshake
    Upgrade: websocket
    Connection: Upgrade
    WebSocket-Origin: <AdresseIPServeur>
    WebSocket-Location: ws://<AdresseIPServeur>:5001
    Sec-WebSocket-Accept: %1
    ]
    SI tabProtocol..Occurrence <> 0 ALORS
    sRes += [RC] + "Sec-WebSocket-Protocol: %2"
    sProtocol = Majuscule(SansEspace(tabProtocol[1]))
    sRes = ChaîneConstruit(sRes, Crypte(HashChaîne(HA_SHA_160,
    sClé + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), "",
    compresseAucun, encodeBASE64), sProtocol + RC + RC)

    SINON
    sRes = ChaîneConstruit(sRes, Crypte(HashChaîne(HA_SHA_160,
    sClé + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), "",
    compresseAucun, encodeBASE64) + RC + RC)
    FIN

    // Envoi la réponse au client
    SocketEcrit(Canal, sRes)

    BOUCLE
    bufFrame est un Buffer = SocketLit(Canal)
    SI 0 = Taille(bufFrame) ALORS
    Trace("Break")
    BREAK
    FIN

    nLongueurFrame est un entier = Asc(bufFrame[[2]]) & 127
    bufMasque est un Buffer
    bufDonne est un Buffer
    SI 126 = nLongueurFrame ALORS
    nLongueurFrame = HexaVersEntier(
    BufferVersHexa(bufFrame[[3 SUR 2]])) //BufferVersEntier(bufFrame, 3, 2)
    bufMasque = bufFrame[[5 A 8]]
    bufDonne = bufFrame[[9 A]]
    SINON SI 127 = nLongueurFrame ALORS
    nLongueurFrame = HexaVersEntier(BufferVersHexa(bufFrame[[3 SUR 8]]))
    bufMasque = bufFrame[[11 A 14]]
    bufDonne = bufFrame[[15 A]]
    SINON
    bufMasque = bufFrame[[3 A 6]]
    bufDonne = bufFrame[[7 A]]
    FIN
    sTexte est une chaîne ANSI
    POUR i = 1 _A_ Taille(bufDonne)
    sTexte += Caract(OUExclusifBinaire(
    Asc(bufDonne[[i]]), Asc(bufMasque[[(i - 1) modulo 4 + 1]])))
    FIN
    Trace(UTF8VersAnsi(sTexte))

    // Formatage de la réponse
    SELON sProtocol
    CAS "XML"
    sRes = [
    <XML status="ok">
    %1
    </XML>
    ]
    CAS "JSON"
    sRes = [
    { "status" : "ok",
    "reponse": "%1" }
    ]
    AUTRE CAS
    sRes = ChaîneVersUTF8("Format non supporté !")
    FIN
    sRes = ChaîneConstruit(sRes, sTexte)

    nLongueurRéponse est un entier = Taille(sRes)
    bufRéponse est un Buffer
    bufRéponse[[1]] = Caract(OUBinaire(0x80, ETBinaire(0x1, 0xF)))
    SI nLongueurRéponse <= 125 ALORS
    bufRéponse[[2]] = Caract(nLongueurRéponse)
    SINON SI nLongueurRéponse <= 65536 ALORS
    bufRéponse[[2]] = Caract(126)
    // Manque l’écriture de la longueur
    bufRéponse += HexaVersBuffer(Droite(EntierVersHexa(nLongueurRéponse), 4))
    SINON
    bufRéponse[[2]] = Caract(127)
    // Manque l’écriture de la longueur
    bufRéponse += HexaVersBuffer(EntierVersHexa(nLongueurRéponse))
    FIN
    SocketEcrit(Canal, bufRéponse + sRes)
    FIN

    FIN
    FIN
Version minimum requise
  • Version 22
Commentaires
Cliquez sur [Ajouter] pour publier un commentaire