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://<ServerIPAddress>:5001", ReturnProc)

// Note: when connecting in secure mode, use 'wss' instead of 'ws'.
// SocketConnect("client", "wss://<ServerIPAddress>:5001", ReturnProc)
// Warning: in server code, you must use 
// SocketCreateSSL instead of SocketCreate

Info("Closing socket...")

SocketClose("client")

Code of return Callback procedure

PROCEDURE ReturnProc(nEvent, sMessage)
gsRes is string = ""

SWITCH nEvent
	CASE SocketOpening: 
		SocketWrite("client", "Text of message sent from the browser.")
		RETURN
	CASE SocketMessage: gsRes += [CR] + "IncomingData: " + sMessage

	CASE SocketClosing: gsRes += [CR] + "Socket closing"

	CASE SocketError: gsRes += [CR] + "Socket error: " + 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:
    // Local procedure code: Listen to messages sent by the socket client.
    
    PROCEDURE pServerSocketListen()
    
    HEADER_WEBSOCKET_CLIENT is string = "Sec-WebSocket-Key: "
    HEADER_WEBSOCKET_PROTOCOL is string = "Sec-WebSocket-Protocol: "
    
    // Create the socket server to listen to the incoming messages
    IF SocketCreate("Server", 5001) = False THEN
    	Error("Creation error " + ErrorInfo(errMessage))
    ELSE
    	// Process (or thread) for listening to messages
    	// This process is run in background task
    	// Listen permanently because we don't know when a message arrives
    	ThreadExecute("Thread1", threadNormal, WaitProcedure)
    END
    
    //-----------------------------------------------------------
    // Procedure called in the listening thread
    INTERNAL PROCEDURE WaitProcedure()
    
    // Endless loop in order to wait for a client connection. 
    // As soon as a client connects to send a message,
    // a thread is started to manage the incoming messages.
    // The ProcedureManagement procedure manages the incoming messages.
    LOOP
    	Multitask(0) 
    	IF SocketWaitForConnection("Server") THEN
    		Channel is string
    		Channel = SocketAccept("Server")
    		SocketChangeTransmissionMode(Channel, SocketNoEndTag)
    		ThreadExecute(Channel, threadNormal, ProcedureManagement, Channel)
    	END
    END
    
    //--------------------------------------------------------------
    // Code of procedure for managing the incoming messages
    INTERNAL PROCEDURE ManageProcedure(Channel)
    
    sRequest is ANSI string
    arrProtocol is array of strings
    sRes is string
    sProtocol is string = "JSON"
    
    // Read the socket until we reach the ending sequence of message
    // In our case, 2 CR characters in a row
    WHILE StringCount(sRequest, CR + CR) = 0
    	sRequest += SocketRead(Channel)
    END
    
    // Process the incoming request
    // The sRequest variable contains the message to process
    // Study the string
    sKey is ANSI string
    FOR EACH STRING sLine OF sRequest SEPARATED BY CR
    	Trace(sLine)
    	IF sLine [=  HEADER_WEBSOCKET_CLIENT THEN
    		sKey = sLine[[Length(HEADER_WEBSOCKET_CLIENT)+1 TO]]
    	ELSE IF sLine [= HEADER_WEBSOCKET_PROTOCOL
    		// Retrieve the protocols
    		StringToArray(ExtractString(sLine, 2, ":"), arrProtocol, ",")
    	END
    END
    
    
    // Prepare the response that will be sent to the 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 arrProtocol..Count <> 0 THEN
    		sRes += [CR] + "Sec-WebSocket-Protocol: %2"
    		sProtocol = Upper(NoSpace(arrProtocol[1]))
    		sRes = StringBuild(sRes, Crypt(HashString(HA_SHA_160, 
    		sKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), "",
    		compressNone, encodeBASE64), sProtocol + CR + CR)
    
    	ELSE
    		sRes = StringBuild(sRes, Crypt(HashString(HA_SHA_160, 
    		sKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), "",
    		compressNone, encodeBASE64) + CR + CR)
    	END
    
    	// Sends the response to the client
    	SocketWrite(Channel, sRes)
    
    	LOOP
    		bufFrame is Buffer = SocketRead(Channel)
    		IF 0 = Length(bufFrame) THEN
    		Trace("Break")
    				BREAK
    		END
    
    		nFrameLength is int = Asc(bufFrame[[2]]) & 127
    		bufMask is Buffer
    		bufData is Buffer
    		IF 126 = nFrameLength THEN
    			nFrameLength = HexaToInt(
    				BufferToHexa(bufFrame[[3 ON 2]])) //BufferToInt(bufFrame, 3, 2)
    			bufMask = bufFrame[[5 TO 8]]
    			bufData = bufFrame[[9 TO]]
    		ELSE IF 127 = nFrameLength THEN
    			nFrameLength = HexaToInt(BufferToHexa(bufFrame[[3 ON 8]]))
    			bufMask = bufFrame[[11 TO 14]]
    			bufData = bufFrame[[15 TO]]
    		ELSE
    			bufMask = bufFrame[[3 TO 6]]
    			bufData = bufFrame[[7 TO]]
    		END
    		sText is ANSI string
    		FOR i = 1 _TO_ Length(bufData)
    			sText += Charact(BitwiseXOR(
    			Asc(bufData[[i]]), Asc(bufMask[[(i - 1) modulo 4 + 1]])))
    		END
    		Trace(UTF8ToAnsi(sText))
    
    		// Format the response
    		SWITCH sProtocol
    			CASE "XML"
    				sRes = [
    					<XML status="ok">
    					%1
    					</XML>
    				]
    			CASE "JSON"
    				sRes = [
    					{ "status": "ok",
    					"reponse": "%1" }
    				]
    			OTHER CASE
    				sRes = StringToUTF8("Format not supported!")
    		END
    		sRes = StringBuild(sRes, sText)
    
    		nResponseLenght is int = Length(sRes)
    		bufResponse is Buffer
    		bufResponse[[1]] = Charact(BitwiseOR(0x80, BitwiseAND(0x1, 0xF)))
    		IF nResponseLength <= 125 THEN
    			bufResponse[[2]] = Charact(nResponseLength)
    		ELSE IF nResponseLength <= 65536 THEN
    			bufResponse[[2]] = Charact(126)
    			// The writing of the length is missing
    			bufResponse += HexaToBuffer(Right(IntToHexa(nResponseLength), 4))
    		ELSE
    			bufResponse[[2]] = Charact(127)
    			// The writing of the length is missing
    			bufResponse += HexaToBuffer(IntToHexa(nResponseLength))
    		END
    		SocketWrite(Channel, bufResponse + sRes)
    		END
    
    	END
    END
Minimum version required
  • Version 22
Comments
Click [Add] to post a comment

Last update: 01/16/2025

Send a report | Local help