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

Delphi Discussion :

Indy TidTCPServer + insertion BD MSSQL


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut Serveur TCP avec ICS ou INDY
    Salut tout le monde

    J'essaye de faire un serveur TCP qui accepte des connexions sur un port déterminé (30005) et qui les passe ensuite dans une base de données (sql server via une procédure stockée).
    Jusque là rien de spécial: j'ai réussi à faire ça avec l'exemple TCPServer de ICS (de overbyte.be): j'insère les lignes (string de 40 caractères max) dans la procédure ProcessData. J'ouvre la connexion à la base de données au démarrage de l'appli (OnCreate). Je ferme et réouvre la procédure stockée à chaque insertion (afin de réinitialiser/vide) le paramètre).

    Ce qui m'étonne c'est que dès que j'ai un nombre de connexions simultanées importants (rien d'énorme: une trentaine), beaucoup (10: en fait quelque soit le nombre de connexions, le sreveur n'acceptera que 20 et rejettra les autres) sont perdues (des données envoyés par un terminal distant: pas de wait/timeout: s'il arrive pas à se connecter il réessaye plus tard).

    Quel est le problème? Que dois-je modifier pour que ça marche? (je suis débutant)

    De l'aide SVP: je bloque depuis deux semaines!!
    Des codes sources (exemples) m'aideraient énormément

    Merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut
    --> J'ai déjà une piste: quand j'élimine l'accès à la base (l'insertion) le serveur accepte toute les connections!
    Dois-je mettre les traitement reliés à la base dans un thread séparé? si oui, comment?

  3. #3
    Membre Expert
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Par défaut
    Sur certain type de base, il existe une commande ou option pour définir un nombre maximal de connection simultannée, exemple :
    http://sqlserver.developpez.com/faq/...ion#Connexion5

  4. #4
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut
    Citation Envoyé par Sub0
    Sur certain type de base, il existe une commande ou option pour définir un nombre maximal de connection simultannée, exemple :
    http://sqlserver.developpez.com/faq/...ion#Connexion5
    Merci pour lé réponse
    En effect: cette limite existe (SELECT @@MAX_CONNECTIONS = 32767 pour ma config).
    Normalement, ça devrait pas poser de problèmes (j'ai 1000 connections simultanées max sur un même port): le vrai problème, c'est que je n'effectue pas les insertions à la base de données dans un thread séparé: j'ai trouvé un excellent tuto à ce sujet: http://bloon.developpez.com/articles.../requetethread
    Je teste ça tout de suite (enfin, le temps que ça me prendra de comprendre et d'essayer :p ) et je reviens ici pour vous dire si ça marche.

    Ceci dit, si quelqu'un à un bout de code, ça m'aiderait énormément

    Encore Merci

  5. #5
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut Indy TidTCPServer + insertion BD MSSQL
    Salut tout le monde

    J'ai fait un serveur tcp simple avec Indy: le serveur accepte les connexions sur un port (30005) et essaye d'insérer les données reçues dans une base de données sql server (sur la même machine).
    J'utilise indy9, voilà mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
      with AThread.Connection do
      begin
        Msg := AThread.Connection.Readln;
        Log.Lines.Add(Msg); //Log: TMemo)
        Log.Lines.Add(IntToStr(AThread.ThreadID));
        with QrInsert do //(QrInsert: TADOuery)
         begin
          Close;
          Parameters.ParamByName('INPUTSTR').Value := Msg;
          ExecSQL;
         end;
      end;
      //AThread.Terminate;
    Ce qui se passe, c'est quand j'ai un nombre important de clients qui envoient les données simultanémment (disons 300 clients envoyant du texte), un nombre important de connections (entre 10 et 30) sont perdues, sans aucun message d'erreur!

    Dois-je créer un nouveau thread pour l'insertion dans la base de données en lui donnant une priorité supérieure (highest)?
    Comment puis-je afficher le nombre de connections en cours (est-ce égal à MonTidTCPServer.threads.LockList.Count ? autrement dit, le nombre de threads est-il égal au nombre de connections?)

    Comment afficher un message d'erreur (côté serveur et pas en le renvoyant au client) quand une connecxion est refusée?

    Merci d'avance pour toute aide

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Par défaut
    Le serveur Sql est t'il configuré de manière à restreindre le nombre de connections simultannées?

  7. #7
    Membre Expert
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Par défaut
    Merci de ne pas recréer un nouveau sujet avec la même question et de poster à la suite de ce sujet.

    -> Sujets fusionnés

  8. #8
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut Indy + Insertion BD
    Désolé:vu que j'ai utilisé ICS en premier lieu (le problème était des connexions timeouté), et que là j'utilise indy (le problème est que j'ai des données qui sont pas insérées dans la base), je pensais que je devais les mettre dans des posts séparés.

    A prioir, ce n'est pas un problème de nombre de connexions (@@MAX_CONNECTIONS=32667)

    J'ai avancé un peu: maintenant j'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    operation cannot be performed while executing asynchronously
    --> dois-je effectuer l'insertion dans un thread séparé? Si oui, comment dois-je faire?

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Par défaut
    visiblement ce sont des requetes simultannées sur une table ou un ensemble de tables.
    Donc se pose la questions de la gestion des conflits d'accés.
    Le mode d'acces est t'il optimiste, pessimiste avec pose de verrous?
    Quel sgdb est utilisé?

  10. #10
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut
    Citation Envoyé par Fabrice ROUXEL 1
    visiblement ce sont des requetes simultannées sur une table ou un ensemble de tables.
    Donc se pose la questions de la gestion des conflits d'accés.
    Le mode d'acces est t'il optimiste, pessimiste avec pose de verrous?
    Quel sgdb est utilisé?
    En fait j'utilise une seule requête (simple TADOQuery avec un paramètre string) sur une seule table sur un seul champ.
    Le mode d'accès est Optimiste.
    L'utilise MS SQL Server 2000 (+SP3).
    Après un peu de recherche sur internet, il semble que le problème soit liè au composant lui même (TADOQuery): certains affirment qu'en utilisant les composants SDAC, ce problème ne se pose pas.

    Serait-il possible que ce soit un problème des compos DbGo Delphi?

  11. #11
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    Ton problème est normal, TIDTCPServer est un composant qui gère les connections par threads. Le seul problème, c'est que tu as un seul TAdoQuery pour plusieurs appels d'insertion.

    Regarde le code que je t'ai fournit un post plus haut ca devrait corriger ton problème.
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  12. #12
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    QrInsert est il créé dynamiquement ?


    [edit]

    essaie comme çà

    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
     
     with AThread.Connection do
      begin
        Msg := AThread.Connection.Readln;
        Log.Lines.Add(Msg); //Log: TMemo)
        Log.Lines.Add(IntToStr(AThread.ThreadID));
        with TadoQuery.Create(nil) do //(QrInsert: TADOuery)
        try
          try
            Close;
            Connection := AdoConnection1; // ici met le bon
            Parameters.ParamByName('INPUTSTR').Value := Msg;
            Connection.BeginTrans; // Démarre la transaction pour éviter les accès concurents
            ExecSQL;
            Connection.commitTrans; // Valide la transaction si tous va bien
          Except on E:Exception do
            begin
              Connection.RollBackTrans; // Annule la transaction en cas d'echec
              ShowmMessage('Erreur : ' E.Message); // à virer après les tests sinon c'est bloquant comme message
            end;
          end; // try except
        finally
          free;
        end; // try
      end;
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  13. #13
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut Changelent de Base de données
    Citation Envoyé par Malatar
    QrInsert est il créé dynamiquement ?


    [edit]

    essaie comme çà

    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
     
     with AThread.Connection do
      begin
        Msg := AThread.Connection.Readln;
        Log.Lines.Add(Msg); //Log: TMemo)
        Log.Lines.Add(IntToStr(AThread.ThreadID));
        with TadoQuery.Create(nil) do //(QrInsert: TADOuery)
        try
          try
            Close;
            Connection := AdoConnection1; // ici met le bon
            Parameters.ParamByName('INPUTSTR').Value := Msg;
            Connection.BeginTrans; // Démarre la transaction pour éviter les accès concurents
            ExecSQL;
            Connection.commitTrans; // Valide la transaction si tous va bien
          Except on E:Exception do
            begin
              Connection.RollBackTrans; // Annule la transaction en cas d'echec
              ShowmMessage('Erreur : ' E.Message); // à virer après les tests sinon c'est bloquant comme message
            end;
          end; // try except
        finally
          free;
        end; // try
      end;
    Pour éviter les problèmes de MS SQL, j'ai changé vers une base firebird (open source, gratuit, stable, rapide: mieux quoi avis qui n'engage que moi

    Je n'ai plus de message d'erreur Vive l'Open Source

    Cette procédure est-elle toujours valable? me permettra-t-elle de mieux 'protéger' ma requête? dois-je mettre dans la reqête dans un thread séparé afin de prévoir une montée en charge (j'ai fait des test jusqu'avec 400 connections simultanées sans problèmes sur mon pc).

    Et si j'insérais mes données via une procédure stockée sur mon firebird: celà améliorerait-il les performances de mon serveur?

    Les composant interbase livrés avec Delphi sont-ils les plus performants?

    Désolé de la 'vague' de questions, mais j'en profite tant que ce thread est encore 'vivant'

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

Discussions similaires

  1. Insertion BdD Mssql depuis flash AS3 via PHP
    Par abort dans le forum ActionScript 3
    Réponses: 0
    Dernier message: 27/05/2009, 09h51
  2. Réponses: 1
    Dernier message: 21/05/2007, 10h44
  3. [INDY] TidTCPServer et Unicode
    Par slimjoe dans le forum Delphi
    Réponses: 2
    Dernier message: 01/08/2006, 22h18
  4. Réponses: 6
    Dernier message: 28/04/2006, 10h56
  5. [Indy/Tidtcpserver] Comment changer de port ?
    Par gilles641 dans le forum Web & réseau
    Réponses: 8
    Dernier message: 20/08/2005, 17h24

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