Limite dimensione messaggi in ricezione e trasmissione con HTTPClient
Home › Forum › Programmazione IEC 61131 (LogicLab) › Limite dimensione messaggi in ricezione e trasmissione con HTTPClient
- Questo topic ha 2 risposte, 1 partecipante ed è stato aggiornato l'ultima volta 1 giorno, 13 ore fa da
Sergio Bertana.
-
AutorePost
-
Giugno 5, 2025 alle 8:35 am #82611
Anonimo
InattivoHo realizzato un sistema con i Vs PLC SlimLine per gestire impianti di climatizzazione. I PLC posti sugli impianti comunicano utilizzando il FB HTTPClient con una applicazione server nel cloud.
Guardando gli esempi del FB HTTPClient ho capito come trasferire in un file i dati ricevuti dal server e quindi gestire ricezione di stringhe dati anche molto lunghe.
Purtroppo non ho capito come inviare stringhe dati al server con il metodo POST utilizzando la proprietà Request del FB HTTPClient. Ho verificato che la lunghezza massima trasferibile è di 512 bytes.
Giugno 5, 2025 alle 8:48 am #82615Sergio Bertana
Amministratore del forumIniziamo con il dire che non c’è limite sulla dimensione dei dati che si possono inviare e/o ricevere in una comunicazione HTTP con il FB HTTPClient. Visto che per i dati in ricezione ti è chiaro come procedere e penso che il programma ST_HTTPClient_ToFile ne sia un esauriente esempio, vediamo come procedere per i dati da inviare al server.
Premesso che si si hanno molti dati da inviare è preferibile utilizzare una richiesta POST in cui i dati vengono inviati nel body senza limiti di lunghezza. Nelle richieste in GET i dati vengono passati nell’URL, che ha una lunghezza definita per ogni server, solitamente mi limito ai 256 caratteri. Ora vediamo il valore 512 a cui penso ti riferissi, negli esempi del FB HTTPClient vedi questo valore ripetuto più volte.
TCPClient.RxSize:=512; //Rx buffer size TCPClient.TxSize:=512; //Tx buffer size HTTPRq.DBSize:=512; //Data buffer size
Nel TCPClient, è definita la dimensione dei buffers Rx e Tx, un pacchetto TCP tipico trasporta fino a 1460 byte di dati, quindi si potrebbero definire questi buffer pari a questa dimensione. Solitamente utilizzo la dimensione 512 per non allocare troppa memoria RAM, il protocollo TCP negozia la quantità dei dati da trasferire in ogni pacchetto dimensionandola alla dimensione buffer. Quindi i dati da ricevere/trasmettere su protocollo TCP saranno frazionati in tanti pacchetti pari alla dimensione definita.
Nel HTTPClient è definita la dimensione del buffer di appoggio per trasmissione/ricezione dati verso stream di comunicazione (TCPClient) l’indirizzo è trasferito in DBAddress. Il FB compone i dati da inviare in questo buffer e poi li invia allo stream definito in File. I dati ricevuti dallo stream sono trasferiti nel buffer e la dimensione dei dati ricevuti è trasferita in DBChars in modo da permettere al programma utente di leggerli.
I dati da inviare al server vanno scritti in un buffer di memoria il cui indirizzo và definito in Request, attivando Send il FB provvederà ad inviare la richiesta inviando la stringa presente nel buffer. Siccome i sistemi SlimLine non hanno molta memoria RAM ipotizzando di dover inviare 4kBytes di dati conviene utilizzare la funzione SysRMAlloc per allocare il buffer, memoria che sarà disallocata al termine dell’invio. L’invio verrà sudiviso in pacchetti di dimensione pari al valore più piccolo tra quelli definiti in DBSize e TxSize.
Giugno 5, 2025 alle 11:02 am #82629Sergio Bertana
Amministratore del forumLa spiegazione magari è più chiara con un programma di esempio. Partendo dal programma ST_HTTPClient ho estratto la parte di comunicazione evidenziando come sia possibile tramite la funzione SysRMAlloc allocare un buffer da 4KBytes per i dati da inviare al server in POST ed un altro buffer da 4KBytes per contenere i dati ricevuti dal server.
La variabile Page da stringa è stata modificata in puntatore a stringa in modo da poter esserre utilizzata per definire l’indirizzo del buffer di ricezione dati di pagina dal server.
- CaseNr=0: Se i buffers sono allocati vengono disallocati e si inizializza il tempo di attesa.
- CaseNr=1: Si attende l’invio dei dati, e si allocano i due buffers di memoria. Siccome potrebbe non esserci memoria disponibile occoe attendere che si liberi memoria per l’allocazione dei buffers. Quando i due buffers sono allocati è possibile compilare la stringa da inviare al server. I buffers allocati sono sempre azzerati.
- CaseNr=2: Si controlla la ricezione di caratteri dal server e i caratteri ricevuti sono trasferiti nel buffer di pagina. Al termine della ricezione si ritorna al Case 0.
Ecco l’estratto del programma da sostituire nel programma ST_HTTPClient di questo articolo.
VAR Page : @STRING; (* Page string *) END_VAR // ------------------------------------------------------------------------- // PROGRAM SEQUENCIES // ------------------------------------------------------------------------- // Program sequencies. CASE (CaseNr) OF // --------------------------------------------------------------------- // Initialize the time to manage acquisition delay. 0: HTTPRq.Send:=FALSE; //Send request IF (HTTPRq.Request <> eNULL) THEN eTO_JUNK(SysRMFree(ADR(HTTPRq.Request))); END_IF; IF (Page <> eNULL) THEN eTO_JUNK(SysRMFree(ADR(Page))); END_IF; TimeBf:=SysTimeGetMs(); //Time buffer (mS) CaseNr:=CaseNr+1; //Program case // --------------------------------------------------------------------- // Wait delay time then initialize buffers and enable client. 1: IF ((SysTimeGetMs()-TimeBf) < TO_UDINT(T#5s)) THEN RETURN; END_IF; IF (HTTPRq.Request = eNULL) THEN IF NOT(SysRMAlloc(4096, ADR(HTTPRq.Request))) THEN RETURN; END_IF; END_IF; IF (Page = eNULL) THEN IF NOT(SysRMAlloc(4096, ADR(Page))) THEN RETURN; END_IF; END_IF; eTO_JUNK(SysVsnprintf(HTTPRq.Request, 4096, ADR('%s'), STRING_TYPE, ADR('Some text'))); eTO_JUNK(SysCVsnprintf(HTTPRq.Request, 4096, ADR('%s'), STRING_TYPE, ADR('More text'))); // ... More SysCVsnprintf to add data eTO_JUNK(SysCVsnprintf(HTTPRq.Request, 4096, ADR('%s'), STRING_TYPE, ADR('More text'))); HTTPRq.Send:=TRUE; //Send request CaseNr:=CaseNr+1; //Program case // --------------------------------------------------------------------- // Header/Page data are received from server by chunked. When a chunk // has been received DBChars returns its length. 2: IF ((HTTPRq.DBChars <> 0) AND HTTPRq.HPSelector) THEN IF ((Sysstrlen(Page)+HTTPRq.DBChars) < 4096) THEN eTO_JUNK(Sysmemmove(eTO_POINTER(Page)+Sysstrlen(Page), HTTPRq.DBAddress, HTTPRq.DBChars)); END_IF; END_IF; // The received page content could be used. IF (HTTPRq.Done) THEN CaseNr:=0; END_IF; END_CASE; // [End of file]
-
AutorePost
- Devi essere connesso per rispondere a questo topic.