Websocket¶
Dans cette leçon nous allons mettre en place un système de chat relativement simple qui utilise les websockets.
Mise en place de la partie client¶
L'interface utilisateur peut être réalisée à l'aide des codes HTML, JavaScript et CSS suivants. Ici le code HTML utilise l'API Bootstrap.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
1 2 3 4 5 6 7 8 9 |
|
Mise en place de la partie serveur¶
Il reste à mettre en place la partie serveur. L'URL construite à la ligne 7
du code HTML ci-dessus référence un script "chat". Nous allons donc créer un
fichier qui corresponde à ce nom. Notre script s'appellera donc chat.ewts
.
Il est également possible de l'appeler chat.script
au besoin.
Le script de la partie serveur est en réalité très simple : il doit
permettre de traiter les 5 types d'événements susceptibles d'arriver en
websocket. Il s'agit des événements open
, message
, binary
, close
et
error
.
Le script est le suivant:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
La première ligne indique que le script ne peut être appelé que pour des requêtes adressées au servlet "websocket".
Les lignes suivantes traitent les 4 types d'événements possibles.
En cas de open
, on envoie un message de salutation à l'utilisateur qui se
connecte, et on annonce à tous les autres utilisateurs qu'une nouvelle
personne s'est connectée.
En cas de message
, on envoie un message à tous les participants. Ici on
utilise des emoji pour distinguer les interlocuteurs.
En cas de close
, on annonce à tous les participants qu'une personne s'est
déconnectée.
En cas d'error
, on ne fait rien de particulier si ce n'est de reprendre
l'erreur dans le log.
Données binaires¶
Jusqu'à présent, nous nous sommes limités à des données textuelles. Il est également possible de gérer des données binaires. Pour cela deux solutions s'offrent à nous:
- Transmettre/Recevoir des données binaires (de type
ArrayBuffer
ouBlob
en javascript) - Encoder les données binaires en base64 (ou autre codage utilisant un alphabet standard) et les transmettre sous forme de texte, comme cela a été fait plus haut.
Nous allons explorer ces deux solutions.
Transmission de données binaires¶
Partie client¶
L'upload de document binaire nécessite une adaptation de l'interface utilisateur. Au niveau de la partie HTML, nous ne faisons que d'ajouter un champ "file" qui permettra de sélectionner un fichier. Le reste du code HTML ne change pas. Pour cette raison, nous ne reprenons ici qu'une partie du code HTML. Les lignes ajoutées sont mises en évidence.
Le code javascript nécessite plus de modifications. Le code CSS quant à lui ne change pas.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
JavaScript permet de gérer les données binaires de différentes façons. Ici, nous utilisons le type Blob pour l'envoi au serveur et le type ArrayBuffer pour traiter les données reçues.
Les modifications portent sur la réception de données et sur l'envoi de données.
Réception
La ligne 6 indique que nous souhaitons recevoir des données binaires de type
ArrayBuffer. Le bloc de lignes 14 à 16 reprend le comportement qui a déjà
été mis en place précédemment pour les données texte. Les lignes 18 à 25
quant à elles gère la réception de données binaires. Ici nous faisons le
choix de traiter les données comme des images PNG. C'est évidemment un choix
arbitraire qui ne peut fonctionner que si l'on sait explicitement que les
données reçues sont de ce type. Nous revenons sur la problématique du type
MIME plus bas.
Envoi
La méthode sendMessage
est modifiée pour gérer l'envoi de données. Elle
vérifie si l'input "file" contient un fichier et se charge de transmettre
celui-ci en tant que Blob le cas échéant.
Partie serveur¶
De base, une application Ewt intègre un buffer capable de stocker jusqu'à 1MB de données binaires. Il est possible d'élargir ce buffer en ajoutant ou complétant le bloc suivant dans la configuration de l'application, en adaptant la taille du buffer. Ici la valeur est exprimée en bytes. Dans l'exemple ci-dessous, on étend donc la taille du buffer à 10MB.
<websocket>
<maxBinaryMessageBufferSize>10485760</maxBinaryMessageBufferSize>
</websocket>
Le script chat.ewts
nécessite quant à lui peut de modifications : on
implémente le cas "binary" qui n'était pas géré dans la version précédente.
Le reste du code ne change pas.
case "binary":
$websocket.send($$.content, { dest: "all" });
break;
Bilan¶
L'envoi et la réception de données binaires sont fonctionnels, mais ils sont limités par le fait que seule les données sont transmises, sans les métadonnées qui gravitent autour. On perd ainsi des informations utiles comme le nom de fichier et le type MIME. Pour pouvoir intégrer ces éléments dans les requêtes et réponses WebSocket, nous allons devoir construire un objet JSON dans lequel les données binaires sont encodées.
Encodage des données binaires¶
L'idée de cette variante est d'encoder les données binaires en base64 et de les inclure dans un objet JSON. Nous en profiterons pour y ajouter les métadonnées relatives au fichier (son nom et son type MIME) bien que dans le cadre de cette leçon nous ne nous en servirons pas.
L'objet JSON sera alors converti en String et transmise sous forme de texte et non plus sous forme de données binaires.
Le volume des données transmissibles sous forme de String est également
limité. Par défaut, il est de 8192 bytes par message. Si on souhaite
intégrer une représentation base64 des données, il convient d'augmenter la
limite du buffer. Pour ce faire, il faut d'ajouter ou compléter le groupe
websocket
du fichier de configuration de l'application avec la propriété
suivante (adapter la valeur selon vos besoins):
<websocket>
<maxTextMessageBufferSize>10485760</maxTextMessageBufferSize>
</websocket>
Ici nous avons augmenté la limite à 10MB.
Partie client¶
Le code HTML est inchangé par rapport à la version précédente. Par contre le code javascript change sensiblement. En réalité nous profitons d'améliorer le design de la zone de messages, même si cela reste largement perfectible. Le rendu final ressemble à ceci:
Le nouveau code JavaScript est repris ci-après en intégralité.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
|
Partie serveur¶
La partie serveur est également passablement remaniée pour que les requêtes et réponses soient traitées comme des objets json.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
Conclusion¶
Nous avons vu comment mettre en place un système de chat simple. En réalité la majeure partie du travail consiste à construire l'interface utilisateur en HTML, JavaScript et CSS. La partie serveur quant à elle est relativement simple à construire.