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!! :pleure: :bug:
Des codes sources (exemples) m'aideraient énormément
Merci d'avance :)
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:
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 :P
Changelent de Base de données
Citation:
Envoyé par Malatar
QrInsert est il créé dynamiquement ?
[edit]
essaie comme çà
Code:
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 :mouarf: avis qui n'engage que moi ;)
Je n'ai plus de message d'erreur :D Vive l'Open Source :D
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' :mouarf:
Plusieurs lignes avec Readln avec Indy TidTCPServer
Citation:
Envoyé par micheln
Merci Beaucoup :) ça a résolu mon problème : le serveur marche comme un charme.
J'ai parlé trop vite :oops:
En fait, le serveur tcp reçoit pour chaque connection, plusieurs lignes de suite: comment dois-je faire pour les insérer dans la base de données?
quelle membre de connection dois-je utiliser: readalldata ?
MERCI D'AVANCE