Bonjour, dans le cas d'un réécriture d'un programme gérant plusieurs accès réseau (2Kbit/s TCP/UDP avec un à quatre modem usb à base de XBee) je voudrais savoir quelle est la meilleure façon de traiter les messages.
La version actuelle utilise les composants UDP Indy en mode threaded et les sockets borland (non Indy) en ctnonblocking.
Cette méthode commence a devenir un peu difficile a maintenir car le code devient indigeste même si le traitement des messages reçu se fait dans des DLL prévues a cet effet.
Ceci est du au fait que de nouvelles fonctionnalités utilisent a chaque fois un nouveau port (par exemple, une fonctionnalité de télémétrie doit être incorporée alors que l'on gère déjà le traitement de capteurs de température et de débitmètre et que derrière ont doit transmettre des messages a une console ou autre).
De même, quand je doit faire un ckeck-up des capteurs(toutes les minutes), le programme se freeze littéralement en attendant la réponse des dits capteurs avant d'envoyer une erreur le cas échéant.
Dans le même acabit, ce sont ces même fonctions qui envoient les requettes SQL pour archiver les messages.
Petit code exemple (j'en ai 5 comme celui-la):
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
 
/*Fonction de décodage des messages du debimetre*/
void __fastcall TMNFRM::DBM_ServUDPRead(TIdUDPListenerThread *AThread, TBytes AData,
          TIdSocketHandle *ABinding)
{
/*Pour suprimmer l'avertissement W8057*/
AThread;AData;ABinding;
/*~Pour suprimmer l'avertissement W8057*/
DBMDecodeFuncDLL = (DBMDEC)GetProcAddress(hDBMDLL, "DBMdecode");
        if (DBMDecodeFuncDLL)
        {
            AnsiString Result;
            Result=DBMDecodeFuncDLL(12,ABinding->PeerIP,AData,DBM_Serv);
            char *c = Result.c_str();
            char tab[6][20];
            int j = 0;
 
            do
                {
                int k = 0;
                while(*c != ';' && *c) tab[j][k++] = *c++;
                tab[j++][k] = 0;
            } while(*c++);
 
Journal->AddLine( StrToInt(tab[0]),AnsiString(tab[1]),AnsiString(tab[2]),AnsiString(tab[3]),StrToFloat(AnsiString(tab[4])),StrToFloat(AnsiString(tab[5])));
if(!strcmp(tab[3],"DBM: Déreg")) //Le capteur entre en veille automatique (vannes fermées)
{
Capteur[StrToInt(tab[0])].Active=false;
Etat_Capteur(Journal->NameById(StrToInt(tab[0])),2);//
CCDate->Cells[1][StrToInt((tab[0]))]=DateToStr(Date())+" "+TimeToStr(Time());
CCDate->Cells[2][StrToInt((tab[0]))]=DateToStr(Date())+" "+TimeToStr(Time());
 
if (Capteur[StrToInt(tab[0])].visible==true)
{
Capteur[StrToInt(tab[0])].PinRadio->Delete();
Capteur[StrToInt(tab[0])].visible=false;
}
}
if(!strcmp(tab[3],"DBM: Notify"))//Le capteur envoie un signal de type Keep_Alive
{
Etat_Capteur(Journal->NameById(StrToInt(tab[0])),5);
Capteur[StrToInt(tab[0])].Active=true;
Capteur[StrToInt(tab[0])].Timerest=Capteur[StrToInt(tab[0])].Timeinit;
}
if(!strcmp(tab[3],"DBM: ACK"))//Le capteur envoie un signal de type Aquittement après une demande de verification
{
Etat_Capteur(Journal->NameById(StrToInt(tab[0])),5);
Capteur[StrToInt(tab[0])].Active=true;
Capteur[StrToInt(tab[0])].Timerest=Capteur[StrToInt(tab[0])].Timeinit;
}
CCDate->Cells[2][StrToInt((tab[0]))]=DateToStr(Date())+" "+TimeToStr(Time());
if(!strcmp(tab[3],"DBM: Enreg"))//Le capteur sort de la veille automatique (vannes en cours d'ouverture)
{
    Capteur[StrToInt(tab[0])].Active=true;
    Capteur[StrToInt(tab[0])].Timerest=Capteur[StrToInt(tab[0])].Timeinit; //recopier pour toutes les réponses Capteurs
 
Etat_Capteur(Journal->NameById(StrToInt(tab[0])),5);
CCDate->Cells[0][StrToInt((tab[0]))]=DateToStr(Date())+" "+TimeToStr(Time());
CCDate->Cells[2][StrToInt((tab[0]))]=DateToStr(Date())+" "+TimeToStr(Time());
AnsiString request;
request="select * from Parametres where id="+(AnsiString)tab[0];
Config_Capteurs->PSTQuery->Active=true;
Config_Capteurs->PSTQuery->Close();
Config_Capteurs->PSTQuery->SQL->Clear();
Config_Capteurs->PSTQuery->SQL->Add(request);
Config_Capteurs->PSTQuery->Open();
int time_N,time_U;
      time_N=Config_Capteurs->PSTQuery->FieldByName("Periode_scrutation")->AsInteger;
      time_U=Config_Capteurs->PSTQuery->FieldByName("Scrutation_alarme")->AsInteger;
if(Config_Capteurs->PSTQuery->FieldByName("Tracking")->AsString=="Vrai" )
{
      Enable(StrToInt(tab[0]),time_N,time_U,true);//Envoie les messages d'auto tracking au capteur (etat normal + alarme)
}
else
{
Disable(StrToInt(tab[0]),time_U); //Envoie les messages d'auto tracking au capteur (alarme uniquement)
}
}
}
}