IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Web & réseau Delphi Discussion :

Identifiant de la connexion après déconnexion


Sujet :

Web & réseau Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Par défaut Identifiant de la connexion après déconnexion
    Bonjour à tous !!

    Voilà j'utilise des PSIONS avec un programme WinDev pour me connecter à mon serveur de socket Delphi...
    J'implémente mon idConnexion de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    procedure TMainForm.ServerSocketClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
    //On fait une requête permettant de regarder si l'adresse IP du scan qui se connecte existe dans la base
    oqConnexion.Close;
    oqConnexion.SQL.Clear;
    oqConnexion.SQL.Add('SELECT * FROM adresseip WHERE adrip = :addIP');
    oqConnexion.DeclareAndSet('addIP', otString, Socket.RemoteAddress);
    oqConnexion.Execute;
    
    //Si aucune correspondance, le scan n'est pas autorisé à se connecter
    If oqConnexion.FieldIsNull('adrip') then
      begin
      MessageDlg('Votre scan n''est pas autorisé à se connecter - Contacter l''administrateur', mtError, [mbOk],0);
      //Fermeture du serveur de socket
      ServerSocket.Close;
      end
    else
      begin
        //Scan autorisé à se connecter
        TraceServeur.Lines.Add('Connexion acceptée par le serveur socket');
        //Récupération de son identifiant de connexion qui est égal au nombre de connexions - 1
        idConnexion := IntToStr(ServerSocket.Socket.ActiveConnections -1);    //On met à jour la table des adresses IP en ajoutant l'identifiant de connexion au scan correspondant
        oqInsertIdConnexion.Close;
        oqInsertIdConnexion.SQL.Clear;
        oqInsertIdConnexion.SQL.Add('UPDATE adresseip SET idconnexion = :monIdConnexion WHERE adrip = :addIP');
        oqInsertIdConnexion.DeclareAndSet('monIdConnexion', otString, idConnexion);
        oqInsertIdConnexion.DeclareAndSet('addIP', otString, Socket.RemoteAddress);
        oqInsertIdConnexion.Execute;
        oqInsertIdConnexion.Session.Commit;
      end;
    end;
    Cependant imaginons deux scans

    - un indice de connexion[0] et
    - un autre indice de connexion[1]

    Si je déconnecte celui de l'indice[0] quand il se reconnecte il se met donc en indice[1] comme le deuxième donc problème !!!

    Si vous pouvez m'aider je suis preneuse ...

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    J'ai déjà pourtant répondu à cette question [D7] Socket récupérer l'indice de connexion et conserver l'Address ou le Handle comme ICI: Utilisation des Tsocket
    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

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Par défaut
    Je t'avoue que j'ai un peu de mal à comprendre ce que tu m'avais mis...

    Je pensais récupérer mon idConnexion et faire une boucle de idconnexion + 1 au nombre d'active connexions soustraire 1 à chaque idconnexion... pour qu'à la prochaine connexion le scan prenne ActiveConnections - 1... mais je sais pas si c'est très catholique...

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Utilise le HANDLE
    Dans OnClientRead de type TSocketNotifyEvent, tu as un paramètre Socket qui contient une propriété Handle
    Pour chaque message reçu stocke cet Handle, il te servira pour retrouver le socket lors de l'émission de la réponse !

    Il ne semble pas très utilise de conserver cela en DB, si le programme tombe, plus aucun ID n'est valable !
    Je suppose que tu as un comportement assez simple !

    Client 1 envoie un message à Server, Server doit répondre à Client 1
    Le Serveur doit juste mémorisé qui a fait une demande pour renvoyer au bon client !

    J'ignore ta structure actuel !
    Tu utilises TServerSocket, vieillo mais efficace !

    Voici ce que j'ai expérimenté en 2001 lorsque j'étais Etudiant en licence !
    Bon, je recevais plus de 5 à 10 messages secondes pouvant générer de 20 à 50 requêtes par secondes (IB6 était à la limite de ses capacités, j'ai découvert en cours de route, que des Requêtes paramètrées et préparées explicitement pouvait améliorer les performances quasiement par 10)
    Ce qui explique un fonctionnement le plus asynchrone que possible et surtout ne pas bloquer OnRead pour ne pas surcharger le buffer TCP\IP

    - Dans OnRead, n'effectue aucun traitement !
    Tu prends le message et son handle de socket, tu copie cela dans un record (pointer avec new) ou un objet, que tu ajoutes à une TThreadList
    Sache que plus OnRead dure et que tu continues à recevoir Windows doit stocker les données en attente de lecture, je n'ai jamais tenté de la bloquer volontairement, mais dépasser 65K je ne sais pas si il pouvait pas y avoir des perte en Win98 ou 2K (OS de l'époque)

    - Dans un Thread, tu lit en boucle la TThreadList
    Tu bloques juste le temps de récupérer le Premier Record, tu relache le lock dès que c'est fait !
    Tu décomposes le message (soit c'est du texte donc découpage copy, split ... ou du binaire, l'idéal car on peut utiliser un record pour transtyper)

    Selon si le message semble correct ou pas, tu l'ajoute à une seconde TThreadList
    Si incorrect, je te laisse imaginer un sytème de log ou de ACK\NAK
    - Dans un 2nd Thread
    Idem, tu prends le premier message, tu le traites (Base de données par exemple), cela peut surement générer 1 ou plusieurs messages
    Tu les stockes dans une 3eme TThreadList

    - Dans une 3eme Thread
    Idem, cela prend un message et le push vers le socket ciblé par le Handle !



    J'ai utilisé ce mécanisme dans plusieurs projets massivement TCP\IP avec contrainte temps-réel, la gestion des destinataires changeait mais le principe de FIFO ne changeait quasiment pas (en fait le Record contenait tous une série de booléen et d'état en toujours genre pour aiguiller l'algo)
    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 éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Par défaut
    Je t'avoue que tu me parle chinois là j'ouvre de grands yeux aaa !! Bref voici mon OnRead :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    procedure TMainForm.ServerSocketClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
    sCodeRecu, sMessageRecu, addIP, codeUser, codeDep, articleReappro, typeReappro, codeTournee, numCmd, numColis, codeRegroup  : String;
    codeValidExpe : string;
    idConnect, bonxtrn, typeRejet : integer;
    aLitSocket : TStringList;
    sNumVersion : String;
     
    begin
    idConnect := -1;
    aLitSocket := TStringList.Create;
    sMessageRecu := '';
    sCodeRecu := '';
    codeUser := '';
    codeDep := '';
    articleReappro :='';
    typeReappro := '';
    bonxtrn := -1;
    codeTournee := '';
    numCmd := '';
    numColis := '';
    codeRegroup := '';
    codeValidExpe := '';
     
    try
      // Tant que je ne trouve pas un # indiquant la fin du code barre, je boucle...
      While Pos('#', sMessageRecu) = 0 do
        begin
        sMessageRecu := Socket.ReceiveText;
        WriteCodeBarre(maDate + ' : Message reçu : ' + sMessageRecu);
     
        // On vérifie que le message reçu ne soit pas vide
        if sMessageRecu = '' then
          exit; //On termine la procédure si on a pas de code barre
     
        // Je remplace les CRLF (=Retour Chariot RC sous WinDev) par des ;
        sMessageRecu := StringReplace(sMessageRecu, CRLF, ';', [rfReplaceAll]);
        //Je sépare ma chaine à chaque ;
        Split(';', sMessageRecu, aLitSocket);
     
        {*Ma chaine est de la forme :
        Soit sur un Intermec TailleSocket + TailleCodeBarre + CodeBarre
        Soit sur un PSION TailleCodeBarre + CodeBarre
        Pour ne pas avoir d'erreur je récupère ma TailleCodeBarre qui est toujours en avant dernière position...*}
     
        addIP := Socket.RemoteAddress;
        idConnect := RetourneIdConnexion(addIP, oqRechercheAddIP);
     
     
        // Les tests qui suivent vérifie le mot clé reçu après le message socket pour savoir quelle procédure appeler
        if Pos('US00', sMessageRecu) > 0 then
          begin
          sCodeRecu := aLitSocket[aLitSocket.Count -2];
          sNumVersion := aLitSocket[aLitSocket.Count -3];
          ControleUser(addIP, sCodeRecu, sNumVersion, ServerSocket, oqRechercheNomScan, OracleSession, idConnect, oqAddUser);
          end
        else
          if Pos('US99', sMessageRecu) > 0 then
            begin
            sCodeRecu := aLitSocket[aLitSocket.Count -2];
            SortirProgramme(addIP, sCodeRecu, ServerSocket, OracleSession, idConnect);
            end
          else
            if Pos('CB', sMessageRecu) > 0 then
              begin
              //...Et mon code barre qui est toujours en dernière position
              sCodeRecu := aLitSocket[aLitSocket.Count -2];
              //On vérifie existence du code barre
              If sCodeRecu= '' then
                begin
                  exit;
                end
              else
                begin
                //Appel de la procédure de recherche de code barre
                RechercheCodeBarre(addIP, sCodeRecu, OracleSession, ServerSocket, oqRechercheCB, idConnect);
                end;
              end
            else
              if Pos('CR01', sMessageRecu) > 0 then
                begin
                sCodeRecu := aLitSocket[aLitSocket.Count -2];
                //Appel de la procédure de recherche du code déposant (client)
                RechercheCodeDep(addIP, sCodeRecu, OracleSession, ServerSocket, oqRechercheDep, idConnect);
                end
              else
                if Pos('CR02', sMessageRecu) > 0 then
                  begin
                  codeUser := aLitSocket[aLitSocket.Count -5];
                  codeDep := aLitSocket[aLitSocket.Count -4];
                  articleReappro := aLitSocket[aLitSocket.Count -3];
                  typeReappro := aLitSocket[aLitSocket.Count -2];
                  sCodeRecu := codeUser +';'+ codeDep +';'+ articleReappro +';' + typeReappro;
                  //Appel de la procédure de recherche du code article
                  RechercheDemandeReappro(addIP, sCodeRecu, ServerSocket, oqRechercheArticle, oqRecupLib, oqMajReappro, idConnect);
                  end
                else
                  if Pos('CR03', sMessageRecu) > 0 then
                    begin
                    codeUser := aLitSocket[aLitSocket.Count -3];
                    bonxtrn := StrToInt(aLitSocket[aLitSocket.Count -2]);
                    //Appel de la procédure permettant de valider une réappro
                    ValidReappro(addIP, codeUser, bonxtrn, oqValidT, oqValidD, oqValidE, oqValidU, oqValidV, ServerSocket, idConnect);
                    end
                  else
                    if Pos('CR05', sMessageRecu) > 0 then
                      begin
                      codeUser := aLitSocket[aLitSocket.Count -4];
                      bonxtrn := StrToInt(aLitSocket[aLitSocket.Count -3]);
                      typeRejet := StrToInt(aLitSocket[aLitSocket.Count -2]);
                      //Appel de la procédure permettant de faire un arrêt sur une réappro
                      ArretReappro(addIP, codeUser, bonxtrn, typeRejet, oqArret, ServerSocket, idConnect);
                      end
                    else
                      if Pos('CC02', sMessageRecu) > 0 then
                        begin
                        codeUser := aLitSocket[aLitSocket.Count -4];
                        codeDep := aLitSocket[aLitSocket.Count -3];
                        codeTournee := aLitSocket[aLitSocket.Count -2];
                        //Appel de la procédure permettant de rechercher un code tournée
                        DemandeTournee(addIP, codeUser, codeDep, codeTournee, oqDemandeTour, ServerSocket, idConnect);
                        end
                      else
                        if Pos('CC03', sMessageRecu) > 0 then
                          begin
                          codeUser :=  aLitSocket[aLitSocket.Count -6];
                          codeDep := aLitSocket[aLitSocket.Count -5];
                          codeTournee := aLitSocket[aLitSocket.Count -4];
                          numCmd := aLitSocket[aLitSocket.Count -2];
                          numColis := aLitSocket[aLitSocket.Count -7];
                          codeRegroup := aLitSocket[aLitSocket.Count -3];
                          //Appel de la procédure permettant de valider une commande de chargement
                          ValidCmdChargement(addIP, codeUser, codeDep, codeTournee, numCmd, codeRegroup, numColis, oqRechercheNomScan, OracleSession, ServerSocket, idConnect);
                          end
                        else
                          if Pos('CC04', sMessageRecu) > 0 then
                            begin
                            codeUser := aLitSocket[aLitSocket.Count -5];
                            codeDep := aLitSocket[aLitSocket.Count -4];
                            codeTournee := aLitSocket[aLitSocket.Count -3];
                            codeValidExpe := aLitSocket[aLitSocket.Count -2];
                            //Appel de la procédure permettant de lancer l'expédition
                            ValidExpedition(addIP, codeUser, codeDep, codeTournee, codeValidExpe, oqRechercheNomScan, OracleSession, ServerSocket, idConnect);
                            end
                          else
                            if Pos('CC05', sMessageRecu) > 0 then
                              begin
                              codeUser :=  aLitSocket[aLitSocket.Count -6];
                              codeDep := aLitSocket[aLitSocket.Count -5];
                              numCmd := aLitSocket[aLitSocket.Count -4];
                              numColis := aLitSocket[aLitSocket.Count -3];
                              codeRegroup := aLitSocket[aLitSocket.Count -2];
                              //Appel de la procédure permettant d'annuler le chargement du colis
                              AnnulColisChargement(addIP, codeDep, numCmd, codeRegroup, numColis, oqRechercheNomScan, OracleSession, ServerSocket, idConnect);
                              end;
        TraceServeur.Lines.Add(Socket.RemoteAddress + ' : ' + sMessageRecu);
     
        end;
    except
      on E : Exception do MessageDlg('Anomalie ServerSocketClientRead', mtWarning, [mbOk], 0);
    end;
    end;
    En fait j'ai besoin de connaitre mon indice de connexion pour savoir à quel scan renvoyer l'info je pensais du coup faire une boucle regarder si l'indice de connexion 0 est pris si oui je passe au suivant sinon je réupère cet indice de connexion ... :
    Voici ce que j'ai commencé à écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        for i:= 0 to ServerSocket.Socket.ActiveConnections do
          begin
          if ServerSocket.Socket.Connections[i]. then
            begin
            idConnexion := IntToStr(i);
            Break;
            end;
          end;
    Je vais essayer de comprendre ce que tu m'as donné ...

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Encore une fois, stocke le Socket.Handle dans idConnect
    Puis je suppose que toutes ces fonctions finissent par répondre par un message !
    Il te suffit d'utiliser ma fonction IndexHandle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function IndexHandle (var ServerSocket : TServerSocket; Handle : Integer) : Integer ;
    var
        I : integer;
    begin
        // Verification de la connexion
        Result := -1 ;
        for I := ServerSocket.Socket.ActiveConnections - 1 downto 0 do begin
            if (Handle) = ServerSocket.Socket.Connections[i].SocketHandle then begin
                Result := I ;
                Break ;
            end;
        end;
    end ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ...
                  Index := IndexHandle(ServerSocket, idConnect) ;
                  ServerSocket.Socket.Connections[Index].SendText(...);
    ....
    Sinon, ton système de message est proche de ce que j'avais déjà fait !
    tu devrais mettres tous les code messages 'US00', 'US99', 'CR01', 'CR02' ... dans un array[] of string et avec AnsiIndexText, tu en récupères l'indice !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    const
      MSG_JUJU_TYPE : array[0..3] of string = ('US00', 'US99', 'CR01', 'CR02');
      MSG_US00 = 0;
      MSG_US99 = 1;
      MSG_CR01 = 2;
      MSG_CR02 = 3;
     
    ...
      case AnsiIndexText(aLitSocket.Strings[???], MSG_JUJU_TYPE) of
        MSG_US00 : begin ... end;
        MSG_US99 : begin ... end;
        MSG_CR01 : begin ... end;
        MSG_CR02 : begin ... end;
      end;
    J'ignore si tu as de la liberté sur le format des messages, mais le type devrait être en TOUT début, facilement extractible !


    Pense qu'avec ton code actuellement tant que OnRead tourne pour un message, les messages peuvent s'accumuler !
    Pense qu'un PopupMenu pourrait bloquer les traitements lors de son surgissement d'où l'utilisation d'un Thread pour miniser l'impact de l'interaction utilisateur !
    Le MessageDlg étant le pire, tout traitement risque de s'arrêter !

    C'est un projet de Picking et de Packing dans un entrepôt ?
    J'ai fait de la logisitique automatisée avec des trieuses de vetêment pour trier les arrivages mais aussi pour préparer les colis envoyés aux boutiques !
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Optimisation de la connexion et déconnexion à une BD
    Par scilab dans le forum Struts 1
    Réponses: 1
    Dernier message: 24/09/2007, 10h03
  2. Rafraîchissement de page après déconnexion
    Par cesoir dans le forum Langage
    Réponses: 8
    Dernier message: 29/03/2007, 09h56
  3. Aucune connexion après l'installation Citrix PS 4.0
    Par genialk2000 dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 23/06/2006, 17h35
  4. MySQL -> pb de connexion et déconnexion
    Par gailup dans le forum Installation
    Réponses: 10
    Dernier message: 24/05/2006, 17h35
  5. Pb de connexion et déconnexion
    Par genki dans le forum MFC
    Réponses: 9
    Dernier message: 30/09/2004, 18h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo