Page 1 sur 2

[R] Communication inter programmes

Posté : ven. 06 sept. 2019 14:59
par scorp84
Bonjour à tous,

Voici mon problème du jour :
J'ai besoin d'interagir sur l'un de mes serveurs sans que les utilisateurs aient à s'y connecter.
Ce serveur est un ACD qui gère la téléphonie.
J'ai besoin de 3 fonctions :
1. Éteindre et redémarrer à distance un programme qui tourne sur l'ACD
2. Rebooter le serveur complètement
3. Registrer des téléphone (via une page web)

Au départ, je me suis orienté vers le TCP avec notamment cette aide :
https://www.autoitscript.com/forum/topi ... d-scripts/

Mais le problème que je rencontre est qu'il me faut une validation de l'exécution des ordres :
1. Programme bien fermé et redémarré
2. Serveur rebooté et programmes relancés

J'ai donc besoin d'une communication dans les 2 sens :
1. Le client demande un ordre
2. le serveur l'exécute et renvoie l'état (OK ou KO)
3. Après le reboot du serveur, j'ai besoin qu'il se reconnecte au "client" (qui devient serveur :evil: ) pour lui dire que cela s'est bien passé (ou pas)

Une autre idée que j'ai eu est de partager entre les 2 une bdd sqlite pour créer une table de dialogue avec demandes et états pour que les 2 puissent dialoguer mais cela m'a semblé lourds.

Auriez-vous des idées ?

Merci d'avance pour votre aide.

BM

Re: [..] Communication inter programmes

Posté : ven. 06 sept. 2019 18:49
par jchd
NamedPipes, MailSlots marchent bien aussi.

Re: [..] Communication inter programmes

Posté : sam. 07 sept. 2019 08:52
par jl56
Bonjour à tous,

Pour faire communiquer 2 softs ensemble j'ai utilisé un simple INI accessible des 2 PC
il n'y a pas besoin de Base de donnée, c'est très léger,simple a coder et très réactif

Cordialement,

JL56

Re: [..] Communication inter programmes

Posté : lun. 09 sept. 2019 09:34
par scorp84
Bonjour à tous les 2,

Merci beaucoup pour vos idées.

@Jl56 : Comment gérez-vous les nouveaux messages ? Lecture en boucle du .INI ? Clé pour signaler un nouveau message ?

Bonne journée à tous.

BM

Re: [..] Communication inter programmes

Posté : lun. 09 sept. 2019 17:22
par jchd
Le problème avec un fichier c'est les conflits d'accès.
Un simple protocole (TCP, UDP, toute forme d'IPC citée) met à l'abri des soucis.

Re: [..] Communication inter programmes

Posté : mar. 10 sept. 2019 09:34
par scorp84
Bonjour JCHD,

Merci pour vos conseils.

Là où je bute, c'est que chaque module soit à la fois client et serveur pour échanger des informations dans les 2 sens.

Mais bon, je ne désespère pas y arriver :lol:

Bonne journée à tous.

BM

Re: [..] Communication inter programmes

Posté : mar. 10 sept. 2019 12:23
par jchd
Voici une base avec laquelle il sera facile de réaliser la tâche en question. Il suffit de rajouter la gestion d'un ficher sur le serveur qui stocke les réponses à renvoyer au(x) clients après redémarrage, via le module client.
Côté client, il suffit d'effectuer la tâche client et d'enchaîner sur la tâche serveur pour pouvoir recevoir le(s) messages de bonne fin.

Il sera bien sûr préférable de réaliser des fonctions pour encapsuler tout ça dans un seul executable (sauf peut être si le reboot prend des semaines). Si le délai est long ou risque de reboot du client, gérer aussi un fichier côté client pour savoir ce qu'on a demandé et où on en est.

Le code joint est brut, il faut se préoccuper de dépassements de délais possibles et autre gestion d'erreur.

On peut aussi utiliser UDP, mais sans garantie absolue de bon acheminement (e.g. réseau saturé).
MyServer.au3
(3.34 Kio) Téléchargé 23 fois
MyServer.au3
(3.34 Kio) Téléchargé 23 fois
MyClient.au3
(2.51 Kio) Téléchargé 22 fois
MyClient.au3
(2.51 Kio) Téléchargé 22 fois

Re: [..] Communication inter programmes

Posté : mar. 10 sept. 2019 15:09
par scorp84
Merci +++ pour ces exemples.

Cordialement.

BM

Re: [R] Communication inter programmes

Posté : mar. 10 sept. 2019 16:14
par jchd
J'ai fait ça un peu (beaucoup !) à l'arrache en partant de l'exemple de TCPSend ou TCPRecv. Ce n'est pas vraiment propre ni bétonné contre les erreurs, j'y ai prêté peu d'attention. Aussi s'il y a plusieurs clients, il faut prévoir un moyen de les reconnaître, mais ça c'est juste une contrainte de plus sur le contenu des messages envoyés/reçus.
Si plusieurs clients, il faudra éviter les blocages pour laisser leur chance à tous les clients et ne pas resté coincé dans une seule boucle. Pour ça, utiliser des timeouts et gérer une file d'attente des messages à émettre.

Donc il y a du boulot pour en faire un machin abouti, mais le principe est grosso modo là.

Re: [R] Communication inter programmes

Posté : mer. 11 sept. 2019 08:26
par scorp84
Bonjour Jchd,

Merci encore beaucoup pour le temps que vous avez pris pour me faire cet exemple.

En fait, je crois que c'est au niveau du fonctionnement concret des échanges TCP/IP que j'ai du mal et ce, malgré votre exemple et le tuto très clair de blacksoul305 :
https://autoitscript.fr/forum/viewtopic.php?t=12000

En fait, ce qui me bloque, c'est que le client va envoyer x ordres au serveur (et ça, grâce à vos exemples, c'est nickel) et dont à un moment, un ordre de redémarrage et qu'après redémarrage les rôles vont s'inverser :
1. Fermer programme ACD (le serveur devra valider au client ou non l'arrêt du programme. Si pb, arrêt de la procédure)
2. Fermer le programme IPBX (le serveur devra valider ou non l'arrêt du programme. Si pb, arrêt de la procédure)
3. Reboot (le serveur devra envoyer la réception de l'ordre de reboot)
4. Le serveur doit rebooter et se connecter au client (inversion des sens client/serveur) pour valider le reboot
5. Relance du programme IPBX (le serveur devra valider ou non la relance du programme. Si pb, arrêt de la procédure)
6. Relance du programme ACD (le serveur devra valider ou non la relance du programme. Si pb, arrêt de la procédure)
7. Validation de la fin de la procédure

Il faudrait idéalement que les 2 soient toujours à l'écoute et connecté à l'autre pour pouvoir envoyer et recevoir des ordres. Mais comment gérer la reconnexion après le redémarrage ?

Est-ce du coup possible ? Et est-ce que le TCP/IP est ce qu'il me faut ?

Merci encore pour vos précieux conseils.

Amicalement.

BM

Re: [R] Communication inter programmes

Posté : mer. 11 sept. 2019 13:22
par jchd
TCP/IP convient très bien surtout grâce à sa robustesse. UDP est moins sûr car les datagrammes peuvent se perdre sans remontée d'erreur, ou arriver en désordre, même si ces cas sont très rares sur un réseau stable et non sursaturé.

Ce qu'il faut déjà c'est définir précisément plusieurs points :

1) il y a-t-il plusieurs clients ? Si oui, il faut les identifier, éventuellement de façon certaine (pour éviter que n'importe qui "impersonnifie" un client légitime avec son portable et s'amuse à mettre le dawa dans l'usine). Si multiplicité de clients, quelle synchronisation entre eux (client A envoie des ordres, et au beau milieu client B demande le reboot) ?

2) il faut définir un organigramme précis de tous les échanges possibles et par là définir un protocole strict avec des états clairement identifiés et des timeouts réalistes. On en déduit les conditions d'erreur et leur traitement (je suis dans tel état et je reçois ceci qui n'est pas prévu ou je ne reçois rien alors que je devrais ; que dois-je faire ?)

Un protocole de communication entre deux entités, c'est la définition stricte des interactions possibles entre deux machines à état (des automates finis déterministes), virtuelles (papier) dans un premier temps, mais qui se concrétise peu à peu au fur et à mesure que tous les détails sont précisés et entrent en jeu (ici ça signifie deux programmes, mais c'est la même démarche entre deux automates mécaniques). Tout ça implique donc l'identification des conditions d'erreur et la définition explicite de leur traitement.

Ce que j'écris peut sembler un étalage de grands mots pour décrire quelque chose de relativement simple, mais sans une approche rigoureuse, on obtient un machin spaguettifié qui ne fonctionne pas correctement dans tous les cas.

Pour reprendre les points de ton message, à ceci près de l'éventuelle multiplicité de clients :

A) les points 1., 2. et 3. sont des ordres particuliers (leur séquencement est figé) qui concluent l'envoi des "X ordres" déjà envoyés. A chaque étape, envoi d'un message ACK (accusé de réception) pour signifier que l'ordre a été bien reçu, puis d'un autre signifiant que l'ordre a bien été exécuté. Si problème, prévoir la gestion d'erreur. Comme TCP est fiable, si un TCPSend ne renvoie pas une erreur, c'est que le serveur l'a bien reçu en intégrité ; il n'y a donc pas lieu de prévoir un ACK sur réception d'un ordre quelconque. Pour la mise au point on peut l'afficher temporairement dans une console locale pour matérialiser la réception, comme mon exemple le fait.

B) au terme de cette action A) globale (à détailler plus loin), le pgm serveur se termine et se se relancera pour prévenir qu'il a bien [re]booté, qu'il a bien [re]lancé ACD puis IPBX. Du coup, on peut mettre cette partie au début du pgm serveur car tout commence par un [re]boot du serveur, lancement d'ACD puis de IPBX et acceptation de connexion du client. On n'a besoin que d'un pgm serveur qui fait tout ça. Mon exemple montre qu'on peut envoyer et recevoir avec la même liaison.

C) Au vu de ça, le client établit une connexion avec le serveur, reçoit une sequence Boot_OK, ACD_OK, IPBX_OK (ou une étape pas_OK et erreur), envoie sa séquence de "X ordres", ses ordres de tuer ACD, puis IPBX, puis reboot. Au terme de la réception d'ACK signifiant que toutes ces étapes se sont bien déroulées, il se relance (car la liaison va être coupée lors du reboot du serveur) et c'est tout, on reboucle sur C).

Il n'y a donc pas "d'inversion client/serveur". C'est juste que le début du protocole impose l'envoi de messages par le serveur vers le client, ce qui revient à dire en gros, "je suis né, tous mes organes sont fonctionnels, tu peux y aller papa, dis-moi quoi faire".

C'est à toi maintenant de voir si cette description grossière s'applique bien à ton cas.

Re: [R] Communication inter programmes

Posté : mer. 11 sept. 2019 13:38
par scorp84
Une fois de plus un immense merci !

C'est sur cette partie que je bloquais :
Il n'y a donc pas "d'inversion client/serveur". C'est juste que le début du protocole impose l'envoi de messages par le serveur vers le client, ce qui revient à dire en gros, "je suis né, tous mes organes sont fonctionnels, tu peux y aller papa, dis-moi quoi faire".
Tu m'a donnés toutes les billes... Y-a plus qu'a :lol:

Merci encore.

Amicalement.

BM

Re: [R] Communication inter programmes

Posté : mer. 11 sept. 2019 17:54
par jl56
Bonjour à tous,

Oui lecture en boucle mais j'utilise plutôt un section pour une nouvelle action
avec IniReadSectionNames je liste les sections puis je les traite selon le besoin et ou leur état.

Vous pouvez une fois le traitement effectué supprimer la section ou avoir une clé exemple genre "traité=oui" que vous modifiez selon votre choix
puis le programme éméteur supprimera la section en lisant que c'est traité (la aussi cet un exemple).

Cordialement,

JL56

Re: [R] Communication inter programmes

Posté : jeu. 12 sept. 2019 08:38
par scorp84
Bonjour JL56,

Votre approche m'intéresse aussi.

Auriez-vous un exemple pour que je comprenne votre façon de faire ?

Merci d'avance.

Amicalement.

BM

Re: [R] Communication inter programmes

Posté : jeu. 12 sept. 2019 16:21
par Tlem
D'après ce que j'ai lu précédemment, il n'y a qu'un serveur et un client. Si j’interprète bien, JL56 privilégie l'utilisation d'un fichier de communication au format .ini (j'avoue que je serais passé par là moi aussi).
J'utiliserais deux fichiers .ini. Un pour les ordres envoyés au serveur et un autre pour le retour d'information. Certes, on peux tout mettre dans le même fichier, mais je trouve que l'utilisation de deux fichiers distinct serait plus 'simple'. ^^

Les fichiers doivent être sur le serveur et les deux machines lisent et écrivent les différentes informations nécessaire au déroulement des actions à réaliser.
Par exemple, un fichier 'Commandes.ini' dans lequel le client vient écrire :

Code : Tout sélectionner

Prog2Close1=ACD   <= Ou le chemin de l'exe ou plus simplement le nom du processus.
Prog2Close2=IPBX
Prog2Close3=
Reboot=1
Le serveur effectue les opérations demandée, remet à vide les valeurs du fichier 'Commandes.ini' et écrit le résultat dans le fichier 'Résultat.ini' :

Code : Tout sélectionner

Prog2Close1=1   <= signifie que le programme 1 à bien été fermé
Prog2Close2=1   <= signifie que le programme 2 à bien été fermé
Prog2Close3=
Reboot=1   <= signifie que le serveur à bien redémarré
Avec un seul fichier, cela pourrait ressembler à ceci :
[Actions]
Prog1=ACD   <= Ou le chemin de l'exe ou plus simplement le nom du processus.
Prog2=IPBX
Prog3=
Reboot=1

[Retours]
Prog1=1
Prog2=1
Prog3=
Reboot=1

Re: [R] Communication inter programmes

Posté : jeu. 12 sept. 2019 17:11
par jchd
Un seul client ? Pas certain je n'ai eu aucune réponse sur ce point.
Mais même avec un seul client, on aura tôt ou tard des conflits d'accès à lire/écrire un bête fichier sans synchronisation.

Re: [R] Communication inter programmes

Posté : jeu. 12 sept. 2019 17:33
par scorp84
Bonsoir,

@Tlem : Merci pour votre exemple.

@Tlem et Jchd : Pour le nombre de client, j'ai compris qu'un seul client permettrait de simplifier les choses (identification du client pour retour, conflits d'écritures, ...). Donc oui, pour l'instant, je vais partir là-dessus.

Je vais continuer mon développement (j'essaye de faire les 2 idées en parallèle, TCP et INI) et le posterai une fois finalisé pour mettre ma solution choisie à disposition de tout le monde.

Merci en tout cas à tous les 2 pour votre aide plus que précieuse.

Amicalement.

BM

Re: [R] Communication inter programmes

Posté : jeu. 12 sept. 2019 17:52
par Tlem
Pas si j'ai bien compris ce que scorp84 souhaite faire.

1 - Le poste 'client' qui si je comprend bien est un poste qui va piloter les actions que le serveur doit effectuer, on initie la procédure => écriture des actions dans le fichier .ini et lecture en boucle des réponses du serveur (ACD fermé ok, IPBX fermé ok, reboot Ok)

2 - Le poste serveur lit le fichier .ini et exécute les actions à réaliser. Prog1=ACD => il doit fermer ACD. Une fois fait il remet la valeur à vide et indique dans l'autre .ini ou dans une autre valeur du .ini principal que ACD a bien été fermé et il effectue toutes les opérations demandée.

3 - Si le client détecte une anomalie a la lecture des réponses du serveur, une action est réalisée ...


On peux aussi réaliser les actions en communication séquentiel :
On lance le script de commande coté client qui écrit la première action à réaliser dans 'Command.ini' (genre : ProcessClose("ACD.exe")) et il attends un certain temps avant de ré-essayer de lire 'Command.ini' pour voir si l'action à été réalisée (et ceci peut être répété un certain nombre de fois). Si le fichier n'existe plus, on passe à la commande suivante et etc ...
Coté serveur, on a un script permanent qui lit en boucle le fichier 'Command.ini' et qui exécute l'action commandée. Si l'action est bien exécutée, le fichier de commande est supprimé.
Pour le reboot, l'utilisation de la clé "Run Once" permettra de supprimer le fichier après le redémarrage.

Re: [R] Communication inter programmes

Posté : jeu. 12 sept. 2019 20:43
par jl56
bonjour à tous,

j'ai tenté de vous faire un exemple rapide sur la partie INI, désolé c'est moche mais j'ai peu de temps.

l'ideal serait d'utiliser un partage sur un autre endroit qui n'est pas concerné par le reboot exemple un autre serveur ou un NAS pour y déposer le fichier INI.

j'ai préparé un test dans ce sens avec un seul fichier
Global $chemin_ini = "\\192.168.0.30\video\surveillance.ini"
If FileExists($chemin_ini) Then
Else
        IniWrite($chemin_ini, "primaire", "mode", "serveur")
        IniWrite($chemin_ini, "primaire", "process01", "WINWORD.EXE")
        IniWrite($chemin_ini, "primaire", "process02", "notepad.exe")
        IniWrite($chemin_ini, "primaire", "etat process01", "oui")
        IniWrite($chemin_ini, "primaire", "etat process02", "oui")
        IniWrite($chemin_ini, "primaire", "reboot", "non")
        IniWrite($chemin_ini, "primaire", "demande arret", "non")
        IniWrite($chemin_ini, "primaire", "nom", "WIN8JL")

        IniWrite($chemin_ini, "secondaire", "mode", "client")
        IniWrite($chemin_ini, "secondaire", "process01", "WINWORD.EXE")
        IniWrite($chemin_ini, "secondaire", "process02", "notepad.exe")
        IniWrite($chemin_ini, "secondaire", "etat process01", "oui")
        IniWrite($chemin_ini, "secondaire", "etat process02", "oui")
        IniWrite($chemin_ini, "secondaire", "reboot", "non")
        IniWrite($chemin_ini, "secondaire", "demande arret", "non")
        IniWrite($chemin_ini, "secondaire", "nom", "srv2")

EndIf



While 1
        If @ComputerName = IniRead($chemin_ini, "primaire", "nom", "") Then

                If IniRead($chemin_ini, "primaire", "mode", "") = "serveur" Then

                        If IniRead($chemin_ini, "primaire", "demande arret", "non") = "oui" Then
                                ProcessClose(IniRead($chemin_ini, "primaire", "process01",""))
                                Sleep(500)
                                If ProcessExists(IniRead($chemin_ini, "primaire", "process01","")) Then
                                Else
                                        IniWrite($chemin_ini, "primaire", "etat process01", "non")
                                EndIf
                                ProcessClose(IniRead($chemin_ini, "primaire", "process02",""))
                                Sleep(500)
                                If ProcessExists(IniRead($chemin_ini, "primaire", "process02","")) Then
                                Else
                                        IniWrite($chemin_ini, "primaire", "etat process02", "non")
                                EndIf
                                IniWrite($chemin_ini, "primaire", "reboot", "non")
                                IniWrite($chemin_ini, "primaire", "mode", "client")
                                IniWrite($chemin_ini, "secondaire", "mode", "serveur")
                                MsgBox(0, "action primaire", "reboot", 10)
                                IniWrite($chemin_ini, "primaire", "etat process02", "non")
                        Else

                        EndIf


                EndIf
        EndIf

        Sleep(100)
WEnd
Pensez a corriger le code avec le nom de vos serveurs ou de votre pc de test et bien sur le chemin du partage avant de démarrer le script
démarrer Word et le notepad sur le serveur/pc de test

je n'ai pas généré la partie client
pour le test j'ouvre le INI avec scite puis je modifie la clé "demande arret" de la section primaire avec oui
dés l'enregistrement de la modif, le word se fermera ainsi que le notepad puis affichage d'un message simulant le reboot

Je sais ça va pas loin mais ça vous démontre quelques possibilités avec un ini

Cordialement,

JL56

Re: [R] Communication inter programmes

Posté : ven. 13 sept. 2019 10:58
par scorp84
Bonjour Jl56,

Merci beaucoup pour votre exemple.

Grâce à tous vos conseils à tous, j'ai maintenant de quoi répondre à mes besoins.

Je suis parti sur un fichier INI unique mais avec une clé de verrouillage pour ne pas avoir de problèmes d'écritures concomitantes.

Une fois terminé, je mettrai le projet sur le forum pour en faire profiter tout le monde.

Merci à tous.

Amicalement.

BM