Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

INDY 10: Intercepter la déconnection du client


Sujet :

Composants VCL Delphi

  1. #1
    Membre confirmé
    INDY 10: Intercepter la déconnection du client
    Bonjour tout le monde,

    J'ai developper une app client/serveur pour l'envois de chaine du serveur vers le client. La communication est bonne pas de soucis sauf que je n'arrive pas intercepter la déconnection du client dans le composant IdTCPServer pour que je puisse effectuer certaines opérations à partir du serveur.
    Pourriez-vous SVP m'eclairer sur le comment faire ?
    Le Savoir c'est le Pouvoir !
    S.Freud

  2. #2
    Débutant
    question stupide, mais vu que tu n'as aucune réponse ....

    as tu pensé à tester tous les événements du serveur ?

    après il faut faire la différence entre une déconnexion normal (bouton, application fermé) et déconnexion à cause d'une coupure internet, application killé, ect qui prend plus de temps à "être détecté"

  3. #3
    Membre confirmé
    Bonjour,

    Citation Envoyé par Coussati

    question stupide, mais vu que tu n'as aucune réponse ....
    Ta question n'est pas stupide elle est intérréssante, je n'y avait pas pensé à tester les evenements du serveur.
    Je le ferais et si j'obtiens des resultats je les posterais. Merci à toi.
    Le Savoir c'est le Pouvoir !
    S.Freud

  4. #4
    Expert éminent sénior
    Pas avec Indy mais avec le TServerSocket, je mets en place un KeepAlive (un truc manuel pas celui du TCP/IP RFC 1122)
    Ainsi passé le délai de lecture (genre toutes les minutes), j'envoie une petite trame, l'échec de l'envoi m'indique si il y a une déconnexion impromptue qui n'a pas été détecté
    Je précise que je suis en mode thread blocking donc je n'utilise pas les évènements de TServerSocket
    C'est valable entre programme utilisant un protocol maison, tu ne peux le faire si ton client n'est prévu pour supporter une trame de keepalive qui pourrait lui provoquer une erreur en réception

    La dernière fois que j'ai utilisé un TIdTcpServer, je l'avais utilisé de la même façon mais je n'avais pas aimé son comportement mais cela datait de 2010.
    Je te conseille quand même vivement le mode Thread que le mode Event
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre confirmé
    Bonjour,

    Citation Envoyé par ShaiLeTroll

    Je te conseille quand même vivement le mode Thread que le mode Event
    Je ne sais pas ce que c'est que le mode Thread j'utilise des commandes pour lire et ecrire depuis le serveur vers le client et vise versa:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
     AContext.Connection.Socket.WriteLn('SUCCESS');
    Variable:= AContext.Connection.Socket.ReadLn;


    Alors je ne sais pas en quel mode je suis.
    Bon je crois avoir trouver, il suffit d'envoyer une chaine depuis le client à la fermeture de l'app et le serveur testera cette chaine si c'est une fermeture ou pas.
    Le Savoir c'est le Pouvoir !
    S.Freud

  6. #6
    Débutant
    pour avoir été intéressé pendant longtemps aux sockets, j'avoue avoir eu pas mal de difficultés quand je me suis lancé

    j'ai une phobie des composants client/server indy ! je n'ai jamais réussi à les utiliser !

    si je me rappelle bien j'arrivais à envoyer des messages au server, mais pas le contraire ! ou alors le server envoyait, mais je devais coder moi même la réception côté client en testant chaque x seconde si un message est arrivé, et je trouvais ça pas du tout pratique ! après c'est peut être moi qui ne savais pas m'en servir ? voyant certaines personnes satisfaites de ces compos ...

    si je ne raconte pas de bêtises, ces compos sont : bloquants et donc contrairement à Tclient/server Socket que j'ai réussi à utiliser avec succès (plus ou moins) ou aux composants tcpclient / tcpserver (dispo dans delphi 7 mais moins connu / utilisé) il n'y a pas de possibilité de choisir entre les 2 modes

  7. #7
    Membre confirmé
    Bonjour,

    Pour moi pas de soucis j'envois des chaines des deux cotés. Bon, je ne suis pas habitué à utilisé Indy mais juste pour des choses simples. J'envois une chaine depuis le client et le serveur fait son traitement et lui renvoi sa réponse suivant le contexte de la demande. Tout ca dans l'evenement OnExecute du compo serveur. Pour l'envoi depuis le serveur j'utilise les mêmes commandes que j'ai cités plus haut.
    Le Savoir c'est le Pouvoir !
    S.Freud

  8. #8
    Débutant
    on dévie du sujet ... et côté client du récupère de quelle manière ? et surtout quel événement ?

    et pour revenir à ta demande, côté serveur, l'évènement "ondisconnect" ne se déclenche pas à la déconnexion d'un client ?

  9. #9
    Membre confirmé
    coté client

    D'abord j'etabli la connexion à l'aide du compo IdTCPClient1 en envoyant l'ip et le nom de la machine pour que le serveur les enregistrent dans une table mémoire:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     Try
      Ip:=getIP;
      Host:=GetLocalComputerName;
      IdTCPClient1.Port := 8080;
      IdTCPClient1.Host := '192.168.1.5';
      IdTCPClient1.Connect;
      Except
      end;


    Ensuite j'envois la chaine au serveur:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    IdTCPClient1.Socket.WriteLn(ip);
    IdTCPClient1.Socket.WriteLn(host);


    Je lis la réponse du serveur:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
     sPrompt := IdTCPClient1.Socket.ReadLn;


    Tout cela dans un bouton il n' y a pas d'evenement coté client.

    coté serveur

    C'est dans l'evenement OnExecute du compo IdTCPServer1 que je recupere la chaine envoyée par le client en faisant une série de testes et renvois la réponse suivant la valeur de cette chaine.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     Chaine:= AContext.Connection.Socket.ReadLn;
     
    If Chaine Then etc.... et vers la fin je fais un Disconnect.
    ..............
    ..............
     
    AContext.Connection.Disconnect;


    Citation Envoyé par Coussati

    et pour revenir à ta demande, côté serveur, l'évènement "ondisconnect" ne se déclenche pas à la déconnexion d'un client ?
    Malheureusement non, je pense que cet evenement concerne la deconnexion du serveur.
    Bon, mais pour mon probleme je pense avoir trouver il suffit de se reconnecter depuis le client et d'envoyer une chaine de deconnexion à inserer dans la série de testes, le serveur la lis et supprime le client enregistré dans la table:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    IdTCPClient1.Socket.WriteLn('DECONNEXION');
    Le Savoir c'est le Pouvoir !
    S.Freud

  10. #10
    Débutant
    "Tout cela dans un bouton il n' y a pas d’événement coté client."

    et bien justement ce n'est pas normal ! tu n'es pas sensé aller cliquer sur un bouton toutes les secondes pour savoir si le serveur a envoyé quelque chose

    pour ce qui est de l’événement, côté serveur, je pense que c'est la déconnexion du client, mais tout bizarrement ça ne fonctionne pas ?

    je pense que tu te compliques beaucoup la vie, mais bon si ça fonctionne et ça te vas, tant mieux

    sinon je suppose que tu n'as jamais essayé Tclientsocket et Tserversocket ?

  11. #11
    Membre confirmé
    Citation Envoyé par Coussati

    et bien justement ce n'est pas normal ! tu n'es pas sensé aller cliquer sur un bouton toutes les secondes pour savoir si le serveur a envoyé quelque chose
    Ah non ! et pardon, pour le bouton c’était le teste que je faisais avant de déplacer le code contenu dans le bouton vers l'application qui, au démarrage, se connecte au serveur. Au départ je faisais cela en dehors de l'app et une fois que ca a marcher pour moi j'ai integrer cela dans l'app.

    Citation Envoyé par Coussati

    pour ce qui est de l’événement, côté serveur, je pense que c'est la déconnexion du client, mais tout bizarrement ça ne fonctionne pas ?
    Je vais revoir ca sinon je bascule vers Tclientsocket et Tserversocket que je n'ai jamais essayer merci à toi.
    Le Savoir c'est le Pouvoir !
    S.Freud

  12. #12
    Membre confirmé
    Juste une petite question:
    Si plusieurs clients se connectent en même temps au serveur es-ce qu'il peut traiter leurs demandes avec la méthode que j'utilise ?
    Je veux dire il n' y a pas une file d'attente à gérer, quelque chose comme une queue list ?
    Le Savoir c'est le Pouvoir !
    S.Freud

  13. #13
    Débutant
    non t'inquiètes ça marche bien

    il y a un exemple très simple sur (de tête) delphipage.free.fr (cherche socket)

  14. #14
    Membre confirmé
    Merci à toi Coussati et à ShaiLeTroll pour le conseil donné j'avais complètement oublier de le remercier
    Le Savoir c'est le Pouvoir !
    S.Freud