WebSocketServer
La classe WebSocketServer
vous permet de créer et configurer un serveur WebSocket en 4D. Une fois que le serveur WebSocket 4D est actif, vous pouvez ouvrir et utiliser des connexions WebSocket entre 4D et les clients en utilisant la classe WebSocketConnection
.
Historique
Release | Modifications |
---|---|
20 | Ajout |
Le protocole WebSocket fournit un canal de communication full-duplex entre un serveur WebSocket et un client (par exemple un navigateur Web). Pour plus d'informations sur les serveurs WebSocket, lisez cette page sur Wikipedia.
Voir également cet article de blog sur le serveur WebSocket 4D.
Conditions requises
Pour créer et gérer votre serveur WebSocket dans 4D, vous devrez utiliser deux classes intégrées à 4D :
- cette classe (
4D.WebSocketServer
) pour gérer le serveur lui-même, - la classe
4D.WebSocketConnection
pour gérer les connexions et les messages.
De plus, vous devrez créer deux classes utilisateurs qui contiendront les fonctions de callback :
- une classe utilisateur pour gérer les connexions serveur,
- une classe utilisateur pour gérer les messages.
Vous devez créer le serveur WebSocket au sein d'un worker pour maintenir la connexion active.
Le serveur Web 4D doit être démarré.
Exemple
Dans cet exemple de base, notre serveur WebSocket renverra les messages en majuscules.
- Créez le serveur WebSocket en utilisant un worker (obligatoire) et passez votre classe de connexion serveur en tant que paramètre :
// Créer une instance de la classe utilisateur
// qui gérera les connexions vers le serveur
var $handler: cs.myServerHandler
$handler := cs.myServerHandler.new()
CALL WORKER("WebSocketServer"; Formula(wss := 4D.WebSocketServer.new($handler)))
// attribuer une variable (wss) au WebSocket vous permet
// d'appeler wss.terminate() par la suite.
- Définissez la classe utilisateur
myServerHandler
contenant la ou les fonction(s) de rappel utilisée(s) pour gérer les connexions au serveur :
// Classe myServerHandler
Function onConnection($wss: Object; $event: Object): Object
// retourne une instance de la classe utilisateur
// qui traitera les messages
return cs.myConnectionHandler.new()
- Définissez la classe utilisateur
myConnectionHandler
contenant la ou les fonction(s) de callback utilisée(s) pour gérer les messages :
// Classe myConnectionHandler
Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
// renvoie le message en majuscules
$ws.send(Uppercase($message.data))
Voir cet article de blog pour un exemple de code Javascript côté client gérant une connexion WebSocket.
Objet WebSocketServer
Les objets WebSocketServer offrent les propriétés et fonctions suivantes :
.connections : Collection toutes les connexions courantes gérées par le serveur WebSocket |
.dataType : Text le type de données reçues ou envoyées |
.handler : Object l'accesseur qui récupère l'objet WSSHandler utilisé pour initier le serveur WebSocket |
.path : Text le pattern du chemin d'accès au serveur WebSocket |
.terminate() .terminate( timeout : Integer ) referme le serveur WebSocket |
.terminated : Boolean True si le serveur WebSocket est fermé |
4D.WebSocketServer.new()
4D.WebSocketServer.new( WSSHandler : Object { ; options : Object } ) : 4D.WebSocketServer
Paramètres | Type | Description | |
---|---|---|---|
WSSHandler | Object | -> | Objet de la classe utilisateur déclarant les callbacks du serveur WebSocket |
options | Object | -> | Paramètres de configuration du WebSocket |
Résultat | 4D.WebSocketServer | <- | Nouvel objet WebSocketServer |
La fonction 4D.WebSocketServer.new()
crée et démarre un serveur WebSocket qui utilisera les callbacks WSSHandler et les options spécifiées (optionnellement), et renvoie un objet 4D.WebSocketServer
.
L'appel de cette fonction nécessite que le serveur Web 4D soit démarré. Le host et le port du serveur WebSocket sont les mêmes que l'hôte et le port du serveur Web 4D.
Paramètre WSSHandler
Dans le paramètre WSSHandler, passez une instance d'une classe utilisateur qui sera appelée chaque fois qu'un événement se produit sur le serveur WebSocket -- essentiellement des événements de connexion. La classe doit définir les fonctions de callback suivantes (seule la fonction onConnection
est obligatoire) :
Propriété | Type | Description | Par défaut |
---|---|---|---|
onConnection | Function | (obligatoire) Callback quand une nouvelle connexion cliente est démarrée (voir ci-dessous) | undefined |
onOpen | Function | Callback quand le serveur WebSocket est démarré (voir ci-dessous) | undefined |
onTerminate | Function | Callback quand le serveur WebSocket est stoppé (voir ci-dessous) | undefined |
onError | Function | Callback quand une erreur est survenue (voir ci-dessous) | undefined |
WSHandler.onConnection(WSServer : Object ; event : Object) : Object | null
Paramètres | Type | Description | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objet serveur WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "connection" | ||
request | Object | Objet request . Contient les informations de la requête de connexion (voir ci-dessous) | ||
Résultat | Object | -> | objet connectionHandler (voir ci-dessous). Si cette fonction renvoie un objet connectionHandler , un objet 4D.WebSocketConnection est automatiquement créé et ajouté à la collection de connexions. Cet objet est alors reçu comme paramètre dans chaque fonction de l'objet connectionHandler . Si la valeur renvoyée est null ou undefined, la connexion est annulée. |
Cette callback est appelée lorsque le handshake est terminé. Elle doit être appelée avec un objet connectionHandler
valide pour créer la connexion WebSocket, sinon la connexion est annulée.
WSHandler.onOpen(WSServer : Object ; event : Object)
Paramètres | Type | Description | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objet serveur WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "open" |
Événement émis lorsque le serveur websocket est démarré.
WSHandler.onTerminate(WSServer : Object ; event : Object)
Paramètres | Type | Description | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objet serveur WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "terminate" |
Événement émis lors de la fermeture du serveur HTTP ou du serveur WebSocket.
WSHandler.onError(WSServer : Object ; event : Object)
Paramètres | Type | Description | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objet serveur WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "error" | ||
errors | Collection | Collection de pile d'erreurs 4D en cas d'erreur d'exécution |
Événement émis lorsqu'une erreur se produit sur le serveur WebSocket.
Exemple de classe WSSHandler
Cet exemple de fonctionnalité de chat basique montre comment gérer les connexions au serveur WebSocket dans une classe WSSHandler.
//myWSServerHandler class
Function onConnection($wss : Object; $event : Object) : Object
If (VerifyAddress($event.request.remoteAddress))
// La méthode VerifyAddress valide l'adresse du client
// L'objet WSConnectionHandler retourné sera utilisé
// par 4D pour instancier l'objet 4D.WebSocketConnection
// lié à cette connexion
return cs.myConnectionHandler.new()
// Voir objet connectionHandler
Else
// La connexion est annulée
return Null
End if
Function onOpen($wss : Object; $event : Object)
LogFile("*** Server started")
Function onTerminate($wss : Object; $event : Object)
LogFile("*** Server closed")
Function onError($wss : Object; $event : Object)
LogFile("!!! Server error: "+$event.errors.first().message)
Objet request
Un objet request
contient les propriétés suivantes :
Paramètres | Type | Description |
---|---|---|
headers | Object | La requête HTTP GET du client. headers.key=value (value peut être une collection si la même clé apparaît plusieurs fois) |
query | Object | Objet qui contient les paramètres de l'URL. Par exemple, si les paramètres sont : ?key1=value1&key2=value2 -> query.key1=value1 , query.key2=value2 |
url | Text | contient uniquement l'URL qui est présente dans la requête HTTP réelle. Ex : GET /status?name=ryan HTTP/1.1 -> url="/status?name=ryan" |
remoteAddress | Text | Adresse IP du client |
Objet connectionHandler
En résultat d'une callback WSHandler.onConnection
, passez un objet connectionHandler
, qui est une instance d'une classe utilisateur qui sera appelée à chaque fois qu'un événement se produira dans la connexion WebSocket -- essentiellement, les messages reçus. La classe doit définir les fonctions de callback suivantes (seule la fonction onMessage
est obligatoire) :
Paramètres | Type | Description |
---|---|---|
onMessage | Function | (obligatoire) Fonction appelée lorsqu'un nouveau message est reçu de cette connexion |
onOpen | Function | Fonction appelée lorsque la 4D.WebSocketConnection est créée |
onTerminate | Function | Fonction appelée lorsque cette connexion est terminée |
onError | Function | Fonction appelée en cas d'erreur |
connectionHandler.onMessage(ws : 4D.WebSocketConnection ; event : Object)
Paramètres | Type | Description | ||
---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objet connexion WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "message" | ||
data | Text / Blob / Object | données envoyées par le client |
Callback pour les données WebSocket. Appelée à chaque fois que le WebSocket reçoit des données.
connectionHandler.onOpen(ws : 4D.WebSocketConnection ; event : Object)
Paramètres | Type | Description | ||
---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objet connexion WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "open" |
Appelée lorsque l'objet connectionHandler
est créé (après l'événement WSS.onConnection
).
connectionHandler.onTerminate(ws : 4D.WebSocketConnection ; event : Object)
Paramètres | Type | Description | ||
---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objet connexion WebSocket courant | |
event | Object | <- | Paramètres | |
type | Text | "terminate" | ||
code | Number | Code de statut indiquant la cause de la fermeture de la connexion. Si la WebSocket ne renvoie pas de code d'erreur, code vaut 1005 si aucune erreur ne s'est produite ou 1006 si une erreur s'est produite. | ||
reason | Text | Chaîne expliquant pourquoi la connexion a été fermée. Si le websocket ne renvoie pas de raison, le code est undefined |
Fonction appelée lorsque la WebSocket est fermée.
connectionHandler.onError(ws : 4D.WebSocketConnection ; event : Object)
Paramètres | Type | Description | |||
---|---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objet connexion WebSocket courant | ||
event | Object | <- | Paramètres | ||
type | Text | "error" | |||
errors | Collection | Collection de piles d'erreurs 4D en cas d'erreur d'exécution |
Fonction appelée en cas d'erreur.
Exemple de classe connectionHandler
Cet exemple de fonctionnalité de chat basique montre comment gérer les messages dans une classe connectionHandler.
// Classe myConnectionHandler
Function onMessage($ws : 4D.WebSocketConnection ; $message : Object)
// Renvoyer le message à tous les clients du chat
This.broadcast($ws;$message.data)
Function onOpen($ws : 4D.WebSocketConnection ; $message : Object)
// Envoyer un message aux nouveaux utilisateurs connectés
$ws.send("Welcome on the chat !")
// Envoyer le message "New client connected" à tous les autres clients de chat
This.broadcast($ws; "New client connected")
Function onTerminate($ws : 4D.WebSocketConnection ; $message : Object)
// Envoi du message "Client déconnecté" à tous les autres clients de chat
This.broadcast($ws; "Client déconnecté")
Function broadcast($ws : 4D.WebSocketConnection ; $message:text)
var $client:4D.WebSocketConnection
// Renvoyer le message à tous les clients de chat
For each ($client; $ws.wss.connections)
// Vérifier que l'id n'est pas la connexion actuelle
If ($client.id#$ws.id)
$client.send($message)
End if
End for each
Paramètre options
Dans le paramètre facultatif options, passez un objet contenant les propriétés suivantes :
Propriété | Type | Description | Par défaut |
---|---|---|---|
path | Text | Représente le chemin d'accès au serveur WebSocket. Si aucun chemin n'est défini, le serveur WebSocket gère toutes les connexions | undefined |
dataType | Text | Type de données reçues par connectionHandler.onMessage et envoyées par la fonction WebSocketConnection.send() . Valeurs : "text", "blob", "object"). Si "objet" : (envoi) transforme l'objet au format json et l'envoie ; (réception) : reçoit le format json et le transforme en objet | text |
.connections
.connections : Collection
Description
La propriété .connections
contient toutes les connexions courantes gérées par le serveur WebSocket. Chaque élément de la collection est un [objet WebSocketConnection
] (WebSocketConnectionClass.md).
Lorsqu'une connexion est terminée, son status
devient "Closed" et elle est supprimée de cette collection.
.dataType
.dataType : Text
Description
La propriété .dataType
contient le type de données reçues ou envoyées.
Cette propriété est en lecture seule.
.handler
.handler : Object
Description
La propriété .handler
contient l'accesseur qui récupère l'objet WSSHandler
utilisé pour initier le serveur WebSocket.
.path
.path : Text
Description
La propriété .path
contient le pattern du chemin d'accès au serveur WebSocket. Si aucun chemin n'a été défini, le serveur WebSocket gère toutes les connexions.
Cette propriété est en lecture seule.
.terminate()
.terminate()
.terminate( timeout : Integer )
Paramètres | Type | Description | |
---|---|---|---|
timeout | Integer | -> | Temps d'attente en secondes avant de terminer le serveur WebSocket |
Description
La fonction .terminate()
referme le serveur WebSocket.
Par défaut, si aucune valeur timeout n'est définie, la fonction initialise le handshake de fermeture et attend de recevoir la trame de fermeture de l'homologue, après quoi elle envoie le paquet FIN pour tenter de fermer proprement la socket. Lorsque la réponse est reçue, le socket est détruit.
Si une valeur timeout est définie :
- lorsque le temps d'attente est atteint, détruit de force la socket.
- si timeout = 0, détruit de force la socket sans trame de fermeture ni d'échange de paquets FIN, et le fait instantanément sans délai d'attente.
.terminated
.terminated : Boolean
Description
La propriété .terminated
contient True si le serveur WebSocket est fermé.
Cette propriété est en lecture seule.