|
|
|
|
|
- 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
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. 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:
| | SocketConnect | Used to connect to the webSockets server. | SocketWrite | Used to send a message to the webSockets server. | SocketExist | Used to check whether the socket used by the connection was not already created. | SocketClose | Used to close the socket once the messages have been sent. |
Code for connecting to the server and for sending messages SocketConnect("client", "ws://<AdresseIPServeur>:5001", ProcRetour)
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: - Create a WINDEV project.
- Create a blank window
- 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:
PROCEDURE pServeurSocketEcoute()
ENTETE_WEBSOCKET_CLIENT is string = "Sec-WebSocket-Key: "
ENTETE_WEBSOCKET_PROTOCOL is string = "Sec-WebSocket-Protocol: "
IF SocketCreate("Serveur", 5001) = False THEN
Error("Erreur de création " + ErrorInfo(errMessage))
ELSE
ThreadExecute("Thread1", threadNormal, ProcédureAttente)
END
INTERNAL PROCEDURE ProcédureAttente()
LOOP
Multitask(0)
IF SocketWaitForConnection("Serveur") THEN
Canal is string
Canal = SocketAccept("Serveur")
SocketChangeTransmissionMode(Canal, SocketNoEndTag)
ThreadExecute(Canal, threadNormal, ProcédureGestion, Canal)
END
END
INTERNAL PROCEDURE ProcédureGestion(Canal)
sRequête is string ANSI
tabProtocol is array of strings
sRes is string
sProtocol is string = "JSON"
WHILE StringCount(sRequête, CR + CR) = 0
sRequête += SocketRead(Canal)
END
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
StringToArray(ExtractString(sLigne, 2, ":"), tabProtocol, ",")
END
END
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
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]]))
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))
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)
bufRéponse += HexaToBuffer(Right(IntToHexa(nLongueurRéponse), 4))
ELSE
bufRéponse[[2]] = Charact(127)
bufRéponse += HexaToBuffer(IntToHexa(nLongueurRéponse))
END
SocketWrite(Canal, bufRéponse + sRes)
END
END
END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|