Intégration avec applications client
Il existe plusieurs façons de permettre la communication entre une application JMap Pro et une autre application client, dite application externe. L'application externe est une application exécutée localement sur le même ordinateur que JMap Pro. On ne parle pas ici d'applications web (HTML, javascript), mais bien d'applications client. L'extension JMap Socket offre une façon simple et efficace de faire cette communication.
Extension Socket pour JMap
L’extension Socket est une extension générique qui permet une communication bidirectionnelle par socket entre des applications externes et les extensions de JMap Pro. Cette extension ne traite pas directement les messages. Son rôle est limité à assurer les communications. Voici un scénario décrivant l’utilisation typique de cette extension :
Une application externe envoie vers JMap l’identifiant d’un élément et celui-ci est automatiquement localisé et sélectionné sur la carte. À l’inverse, l’utilisateur clique sur un élément de la carte et JMap envoie l’identifiant de l’élément vers l’application externe qui affiche un formulaire des propriétés de l’élément.
Description du fonctionnement général
L’extension Socket offre un moyen standard de communication permettant aux extensions de JMap de communiquer avec des applications externes. Les applications externes sont des applications exécutées localement, sur le même ordinateur que JMap Pro. Il peut s’agir d’applications écrites dans n’importe que langage de programmation (Java, C++, Windev, C#, VB.NET, etc.). Notez que les applications web (HTML, javascript, etc.) ne sont pas supportées par cette méthode d’intégration. D’autres méthodes conviennent mieux aux applications web (voir Communication Java - Javascript).
Pour communiquer, les applications externes et les extensions JMap s’envoient des messages qui sont en réalité des tableaux d’octets. Le contenu des ces tableaux d’octets est interprété de part et d’autre, l’extension Socket n’interprétant pas leur contenu.
C’est toujours l’application externe qui se connecte vers JMap en premier, en ouvrant un socket vers le port configuré dans l’extension Socket (fichier socket.properties). Par la suite, c’est encore l’application externe qui effectue la première communication. Cette première communication est spéciale et s’appelle le handshake. Lors du handshake, l’application externe indique son identifiant unique (une chaîne de caractères identifiant l’application).
L’extension de JMap qui désire communiquer avec l’application externe doit de son côté s’enregistrer auprès de l’extension Socket. Elle doit fournir le même identifiant que l’application externe. C’est cet identifiant qui permet de faire le lien entre les deux.
Par la suite, l’application externe tout comme l’extension JMap peuvent s’envoyer des messages à tout moment de part et d’autre. Chaque partie (l’application externe ou l’extension) est responsable d’interpréter les messages et de prendre les actions voulues.
Optionnellement, l’extension Socket peut démarrer l’application externe si celle-ci ne répond pas. Une fois démarrée, l’application externe pourra initier les communications, tel que décrit plus haut.
Programmation du côté de l’application externe
Les exemples de code qui suivent sont en langage Java. Une application externe programmée dans un autre langage devrait implémenter la même logique, dans le langage de de l’application.
1. Ouverture d’un socket en utilisant l’adresse 127.0.0.1 et le port 12351):
Socket socket = new Socket(“127.0.0.1”, 12351);
|
2. Envoi du message de handshake
Le message de handshake sera reçu et interprété par l’extension Socket uniquement. Remarquez que le nombre d’octets du message doit précéder le contenu du message. Le contenu du message est envoyé sous la forme d’un tableau d’octets. L’encodage des caractères (charset) de ce message est défini dans la configuration de l’extension Socket (fichier socket.properties).
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
String handshake = "handshake:MyIdentifier"; dos.writeInt(handshake.getBytes().length); dos.write(handshake.getBytes()); dos.flush();
|
3. Envoi des messages subséquents
Les messages subséquents sont envoyés de la même manière que le message de handshake. Par contre, ils seront reçus et interprétés par les extensions enregistrées avec le même identifiant. Les extensions qui reçoivent les messages doivent donc être en mesure de comprendre le contenu des messages et d’effectuer les actions correspondantes. L’encodage des caractères du message est libre et doit être convenu de l’extension et de l’application externe.
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
String message = "locate :id=333"; dos.writeInt(message.getBytes().length); dos.write(message.getBytes()); dos.flush();
|
4. Réception des messages en provenance de JMap
La réception des messages se fait par le même socket que l’envoi. La longueur du message est lue en premier, et ensuite le tableau d’octets du message. Notez que la réception devrait se faire de manière asynchrone, dans une thread à part.
DataInputStream dis = new DataInputStream(socket.getInputStream());
int length = dis.readInt(); if (length > 0) { byte[] messageBytes = new byte[length]; dis.readFully(messageBytes); }
|
Programmation du côté de l’extension JMap
L’exemple suivant montre comment enregistrer une extension JMap auprès de l’extension Socket afin d’être averti en cas de connexion, de déconnexion et de réception de messages en provenance de l’application externe. Ce code pourrait être placé dans la méthode init() de l’extension JMap.
SocketClientExtension.register(new SocketClient() { @Override public void socketMessageReceived(byte[] bytes) { String data = new String(bytes /*, Charset.forName("ISO-8859-5")*/);
// Interpret content of data… }
@Override public void socketConnectionOpened() { }
@Override public void socketConnectionClosed() { }
@Override public String getIdentifier() { return "MyIdentifier"; }
@Override public String getExecutable() { // Optional - return null if not needed return "c:/external_app.exe"; } });
|
L’exemple suivant montre comment envoyer un message vers l’application externe à partir de l’extension JMap.
String message = "openform: id =99"; byte[] bytes = message.getBytes(); SocketClientManager.getInstance().sendMessage("MyIdentifier" , bytes);
|