ONLINE HELP
 WINDEVWEBDEV AND WINDEV MOBILE

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
WindowsLinuxUniversal Windows 10 AppJavaReports and QueriesUser code (UMC)
WEBDEV
WindowsLinuxPHPWEBDEV - Browser code
WINDEV Mobile
AndroidAndroid Widget iPhone/iPadIOS WidgetApple WatchMac CatalystUniversal Windows 10 App
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.
Remark: The WebSockets server can correspond to a WINDEV or WEBDEV application, or to another one. 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)
 
// Remark: for a connection in safe mode, use 'wss' instead of 'ws'
// SocketConnect("client", "wss://<ServerIPAddress>:5001", ReturnProc)
// Caution: 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] + "Receiving message: " + sMessage
 
CASE SocketClosing: gsRes += [CR] + "Closing the socket"
 
CASE SocketError: gsRes += [CR] + "Error of 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 (IP address of server, 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 of local procedure: Listen to the 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 À]]
    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: <ServerIPAddress>
    WebSocket-Location: ws://<ServerIPAddress>:5001
    Sec-WebSocket-Accept: %1
    ]
    IF arrProtocol..Occurrence <> 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")
    SORTIR
    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(BinaryXOR(
    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",
    "response": "%1" }
    ]
    OTHER CASE
    sRes = StringToUTF8("Format not supported!")
    END
    sRes = StringBuild(sRes, sText)
     
    nResponseLenght is int = Length(sRes)
    bufResponse is Buffer
    bufResponse[[1]] = Charact(BinaryOR(0x80, BinaryAND(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: 05/26/2022

Send a report | Local help