ONLINE HELP
 WINDEVWEBDEV AND WINDEV MOBILE

This content has been translated automatically.  Click here  to view the French version.
Help / WLanguage / WLanguage functions / Communication / Sockets
  • Overview
  • Operating mode
  • Example
  • Code for connecting to the server and for sending messages
  • Code of return Callback procedure
  • Example of WebSockets server developed in WINDEV
WINDEV
WindowsLinuxJavaReports and QueriesUser code (UMC)
WEBDEV
WindowsLinuxPHPWEBDEV - Browser code
WINDEV Mobile
AndroidAndroid Widget iPhone/iPadIOS WidgetApple WatchMac Catalyst
Others
Stored procedures
Overview
The WebSockets are used to communicate from a Web application (Intranet or Internet site run in a browser) to a Web server by using sockets.
Note: The WebSockets server may correspond to a WINDEV, WEBDEV or other application.. This page presents an example of WebSockets server developed in WLanguage with WINDEV.
Operating mode
To send a message from a Web application by using the WebSockets, the following processes must be programmed on browser side:
  • connection to server,
  • sending message,
  • disconnection.
To do so, you will use the same WLanguage functions as the ones used on server side:
SocketConnectUsed to connect to the webSockets server.
SocketWriteUsed to send a message to the webSockets server.
SocketExistUsed to check whether the socket used by the connection was not already created.
SocketCloseUsed to close the socket once the messages have been sent.
Example

Code for connecting to the server and for sending messages

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

// Remarque : en cas de connexion en mode sécurisé, utiliser 'wss' à la place de 'ws'
// SocketConnecte("client", "wss://<AdresseIPServeur>:5001", ProcRetour)
// Attention : en code serveur, il est nécessaire d'utiliser 
// la fonction SocketCréeSSL à la place de la fonction SocketCrée

Info("fermeture socket...")

SocketClose("client")

Code of return Callback procedure

PROCEDURE ProcRetour(nEvenement, sMessage)
gsRes is string = ""

SWITCH nEvenement
	CASE SocketOpening : 
		SocketWrite("client", "Texte du message envoyé depuis le navigateur.")
		RETURN
	CASE SocketMessage : gsRes += [CR] + "Réception du message : " + sMessage

	CASE SocketClosing : gsRes += [CR] + "Fermeture de la socket"

	CASE SocketError : gsRes += [CR] + "Erreur de la socket : " + sMessage
		RETURN
	OTHER CASE

END
Info(gsRes)
Example of WebSockets server developed in WINDEV
Let's see an example of code used to develop a WebSockets server with WINDEV. This code must be adapted according to your configuration and to your requirements (server IP address, ports to open, ...).
Before modifying this example, you must be familiar with the technique and theory of WebSockets. The purpose of this example is not to expliain the theorical operating mode of WebSockets. It just explains how to use WebSockets.
To create a WebSocket server in WINDEV:
  1. Create a WINDEV project.
  2. Create a blank window
  3. Create a local procedure (pServerSocketListen for example) to listen to the messages sent by the client from its Web site. The code of this local procedure is as follows:
    // Code de la procédure locale : Ecoute des messages envoyés par le client socket.
    
    PROCEDURE pServeurSocketEcoute()
    
    ENTETE_WEBSOCKET_CLIENT is string = "Sec-WebSocket-Key: "
    ENTETE_WEBSOCKET_PROTOCOL is string = "Sec-WebSocket-Protocol: "
    
    // Création du serveur de sockets pour effectuer l'écoute des messages arrivants
    IF SocketCreate("Serveur", 5001) = False THEN
    	Error("Erreur de création " + ErrorInfo(errMessage))
    ELSE
    	// 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
    	ThreadExecute("Thread1", threadNormal, ProcédureAttente)
    END
    
    //-----------------------------------------------------------
    // Procédure appelée dans le thread d'écoute
    INTERNAL PROCEDURE 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.
    LOOP
    	Multitask(0) 
    	IF SocketWaitForConnection("Serveur") THEN
    		Canal is string
    		Canal = SocketAccept("Serveur")
    		SocketChangeTransmissionMode(Canal, SocketNoEndTag)
    		ThreadExecute(Canal, threadNormal, ProcédureGestion, Canal)
    	END
    END
    
    //--------------------------------------------------------------
    // Code de la procédure de gestion des messages arrivants
    INTERNAL PROCEDURE ProcédureGestion(Canal)
    
    sRequête is string ANSI
    tabProtocol is array of strings
    sRes is string
    sProtocol is string = "JSON"
    
    // Lecture de la socket jusqu'à avoir la séquence de terminaison d'un message
    // Dans notre cas, 2 RC qui se suivent
    WHILE StringCount(sRequête, CR + CR) = 0
    	sRequête += SocketRead(Canal)
    END
    
    // Traitement de la requête qui arrive
    // La variable sRequête contient le message à traiter
    // On analyse la chaîne
    sClé is string ANSI
    FOR EACH STRING sLigne OF sRequête SEPARATED BY CR
    	Trace(sLigne)
    	IF sLigne [=  ENTETE_WEBSOCKET_CLIENT THEN
    		sClé = sLigne[[Length(ENTETE_WEBSOCKET_CLIENT)+1 TO]]
    	ELSE IF sLigne [= ENTETE_WEBSOCKET_PROTOCOL
    		// Récupération des protocoles
    		StringToArray(ExtractString(sLigne, 2, ":"), tabProtocol, ",")
    	END
    END
    
    
    // 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
    	]
    	IF tabProtocol.Count <> 0 THEN
    		sRes += [CR] + "Sec-WebSocket-Protocol: %2"
    		sProtocol = Upper(NoSpace(tabProtocol[1]))
    		sRes = StringBuild(sRes, Encrypt(HashString(HA_SHA_160, 
    		sClé + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), "",
    		compressNone, encodeBASE64), sProtocol + CR + CR)
    
    	ELSE
    		sRes = StringBuild(sRes, Encrypt(HashString(HA_SHA_160, 
    		sClé + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), "",
    		compressNone, encodeBASE64) + CR + CR)
    	END
    
    	// Envoi la réponse au client
    	SocketWrite(Canal, sRes)
    
    	LOOP
    		bufFrame is Buffer = SocketRead(Canal)
    		IF 0 = Length(bufFrame) THEN
    		Trace("Break")
    				BREAK
    		END
    
    		nLongueurFrame is int = Asc(bufFrame[[2]]) & 127
    		bufMasque is Buffer
    		bufDonne is Buffer
    		IF 126 = nLongueurFrame THEN
    			nLongueurFrame = HexaToInt(
    				BufferToHexa(bufFrame[[3 ON 2]])) //BufferVersEntier(bufFrame, 3, 2)
    			bufMasque = bufFrame[[5 TO 8]]
    			bufDonne = bufFrame[[9 TO]]
    		ELSE IF 127 = nLongueurFrame THEN
    			nLongueurFrame = HexaToInt(BufferToHexa(bufFrame[[3 ON 8]]))
    			bufMasque = bufFrame[[11 TO 14]]
    			bufDonne = bufFrame[[15 TO]]
    		ELSE
    			bufMasque = bufFrame[[3 TO 6]]
    			bufDonne = bufFrame[[7 TO]]
    		END
    		sTexte is string ANSI
    		FOR i = 1 _TO_ Length(bufDonne)
    			sTexte += Charact(BitwiseXOR(
    			Asc(bufDonne[[i]]), Asc(bufMasque[[(i - 1) modulo 4 + 1]])))
    		END
    		Trace(UTF8ToAnsi(sTexte))
    
    		// Formatage de la réponse
    		SWITCH sProtocol
    			CASE "XML"
    				sRes = [
    					<XML status="ok">
    					%1
    					</XML>
    				]
    			CASE "JSON"
    				sRes = [
    					{ "status" : "ok",
    					"reponse": "%1" }
    				]
    			OTHER CASE
    				sRes = StringToUTF8("Format non supporté !")
    		END
    		sRes = StringBuild(sRes, sTexte)
    
    		nLongueurRéponse is int = Length(sRes)
    		bufRéponse is Buffer
    		bufRéponse[[1]] = Charact(BitwiseOR(0x80, BitwiseAND(0x1, 0xF)))
    		IF nLongueurRéponse <= 125 THEN
    			bufRéponse[[2]] = Charact(nLongueurRéponse)
    		ELSE IF nLongueurRéponse <= 65536 THEN
    			bufRéponse[[2]] = Charact(126)
    			// Manque l'écriture de la longueur
    			bufRéponse += HexaToBuffer(Right(IntToHexa(nLongueurRéponse), 4))
    		ELSE
    			bufRéponse[[2]] = Charact(127)
    			// Manque l'écriture de la longueur
    			bufRéponse += HexaToBuffer(IntToHexa(nLongueurRéponse))
    		END
    		SocketWrite(Canal, bufRéponse + sRes)
    		END
    
    	END
    END
Minimum version required
  • Version 22
Comments
Click [Add] to post a comment

Last update: 03/28/2025

Send a report | Local help