HTTPServer, HTTP server management

  1. Home
  2. Knowledge Base
  3. Manualistica
  4. Programmazione IEC 61131-3
  5. Libreria comunicazione HTTP
  6. HTTPServer, HTTP server management

Questo blocco funzione esegue la gestione di un server HTTP, è un blocco funzione protetto per utilizzarlo occorre richiedere il codice di protezione. E' comunque possibile utilizzarlo liberamente in modo test per 30 Min, terminato il tempo il FB continuerà a funzionare ma non gestirà più le variabili pHeader e pRxData.

Attivando Enable è messo in ascolto sulla porta indicata in Port un server HTTP e sono accettate il numero di connessioni definito in AConnections. In TCPBSize occorre definire la dimensione dei buffers allocati con SysRMalloc per la gestione dei pacchetti TCP in trasmissione e ricezione. La dimensione minima è 256 bytes, aumentando la dimensione si velocizza il trasferimento (Sono effettuati meno frazionamenti). E' inutile definire lunghezze superiori al limite del pacchetto TCP 1500 bytes.

In HTTPBSize occorre definire la dimensione del buffer allocato con SysRMalloc per contenere i dati ricevuti in richiesta (Header e dati) ed il contenuto della pagina di risposta da inviare al client. In HPath occorre definire il  percorso della cartella dove si trovano i files gestiti dal server. In PDefault occorre definire la pagina di default da visualizzare su richiesta del solo indirizzo IP del server.

Alla ricezione di una richiesta dal client si attiva RRcvd e sono valorizzati pPage con indirizzo stringa di definizione pagina richiesta, pHeader con indirizzo buffer memorizzazione header ricevuto, pRxData con indirizzo buffer dati di pagina ricevuti e RxDSize con la dimensione dei dati ricevuti.

Il programma utente potrà acquisire i dati e preparare la pagina di risposta da inviare al client che deve essere trasferita nel buffer indirizzato da pTxData, Terminata al compilazione della risposta si trasferisce in TxDSize la dimensione dei dati da trasmettere e si attiva RAck. Nota: la scrittura dei dati và a sovrascrivere i dati ricevuti.

Attivando RNAck verrà inviato al client la risposta 404 di pagina non trovata. Eventuali headers aggiuntivi da inviare al client insieme alla risposta si potranno definire passandone l'indirizzo in Header.

Function block
CODESYS: Non disponibile
LogicLab: eLLabHTTPLib

Enable (BOOL) Comando abilitazione server.

SpyOn (BOOL) Se attivo permette di spiare il funzionamento del FB (Vedi articolo).

RAck (BOOL) Settato da programma forza invio header 200 Ok seguito dai dati di pagina.

RNack (BOOL) Settato da programma forza invio header 400 Not found.

Port (UINT) Porta TCP su cui viene posto in ascolto il server.

AConnections (USINT) Numero di connessioni HTTP contemporanee accettate.

TCPBSize (UINT) Dimensione buffer TCP. Determina la dimensione massima dei pacchetti TCP in ricezione e trasmissione

HTTPBSize (UINT) Dimensione buffer HTPP. Determina la dimensione massima dei dati HTTP in ricezione e trasmissione.

TxDSize (UDINT) Dimensione dati da inviare al client e caricati in buffer pTxData.

Header (@STRING) Indirizzo stringa header, se NULL viene inviato l'header standard. E' possibile definire parametri da inviare con l'header della risposta.

HPath (@STRING) Percorso della cartella dove si trovano i files gestiti dal server. Su richiesta pagina viene ricercato il file in questa cartella, se presente viene ritornato al client, se non presente si attiva RRcvd per poter gestire la richiesta da programma.

PDefault (@STRING) Definizione pagina di default ritornata su richiesta del solo indirizzo IP.

Timeout (REAL) Timeout esecuzione (S).

RRcvd (BOOL) Si attiva su ricezione richiesta HTTP, alla attivazione sono validi i dati in pPage, pHeader, pRxData e RxDSize. Si resetta ala attivazione di RAck o RNAck da programma utente.

Fault (BOOL) Attivo per un loop di programma se errore gestione.

pPage (@STRING) Puntatore al buffer che contiene pagina richiesta ricevuta dal client. Il dato è valido alla attivazione di RRcvd, rimane valido fino alla attivazione di RAck o RNAck.

pHeader (@STRING) Puntatore al buffer che contiene header richiesta ricevuto dal client. Il dato è valido alla attivazione di RRcvd, rimane valido fino alla attivazione di RAck o RNAck.

pRxData (@BYTE) Puntatore al buffer dati ricevuti dal client su richieste GET, PUT, POST. Il dato è valido alla attivazione di RRcvd, rimane valido fino alla attivazione di RAck o RNAck.

pTxData (@BYTE) Puntatore al buffer dati da trasmettere al client. Alla attivazione di RRcvd dopo avere acquisito i dati ricevuti dai buffers pPage, pHeader, pData è possibile trasferire nel buffer i dati da inviare al client. Dopo avere trasferito i dati attivare RAck.

RxDSize (UDINT) Dimensione dati ricevuti dal client.

Spionaggio funzionamento

Se SpyOn attivo viene eseguita la funzione SysSpyData che permette di spiare il funzionamento della FB. Sono previsti vari livelli di triggers.

Errori

In caso di errore si attiva l'uscita Fault, con la funzione SysGetLastError è possibile rilevare il codice di errore. Fare riferimento alla tabella seguente per la descrizione.

Esempi

Come utilizzare gli esempi.
Viene istanziato un server HTTP sulla porta 2000, eseguendo una richiesta in GET della pagina Division.php sono acquisiti i valori di dividendo e divisore e viene ritornato il risultato della divisione. Per testare il programma da un browser usare il link xxx.xxx.xxx.xxx:2000/Division.php?Dividend=500&Divisor=10, sostituendo alle x l'indirizzo IP del sistema. La pagina richiesta ed i dati inviati in GET sono copiati in due buffers per poterli visualizzare da debug.

Viene fornita anche la pagina Home.htm di esempio da trasferire nella cartella del server per testarne il funzionamento.

Rimando a questo articolo per un esempio con aggiornamento pagina in Ajax.

LogicLab (Ptp156)
PROGRAM ST_HTTPServer
VAR
    i : UDINT; (* Auxiliary variable *)
    Ptr : @STRING; (* Auxiliary pointer *)
    CaseNr : USINT; (* Program case *)
    Error : USINT; (* Error number *)
    Dividend : REAL; (* Dividend value *)
    Divisor : REAL; (* Divisor value *)
    Result : REAL; (* Result value *)
    RPage : STRING[ 64 ]; (* Page requested *)
    RData : STRING[ 64 ]; (* Data on request *)
    HTTPSv : HTTPServer; (* HTTP server *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_HTTPServer"
// *****************************************************************************
// The program instantiates a HTTP server om port 2000 that accepts up 2
// simultaneus connections.
//
// If the client (ie Web browser) connects to it and requests a page with GET
// parameters it reads the parameters and returns the page. The program can
// be tested with the example of the HTTPClient.
//
// It's possible use a browser to connect to the device IP and request:
// xxx.xxx.xxx.xxx:2000/Division.php?Dividend=500&Divisor=10
// it will return a message with the division result.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATIONS
    // -------------------------------------------------------------------------
    // Program initializations.

    IF (SysFirstLoop) THEN
        HTTPSv.Enable:=TRUE; //Server enable        
        HTTPSv.SpyOn:=TRUE; //Spy active        
        HTTPSv.Port:=2000; //TCP Port
        HTTPSv.AConnections:=2; //Accepted connections        
        HTTPSv.TCPBSize:=1024; //TCP buffer size        
        HTTPSv.HTTPBSize:=512; //HTTP buffer size        
        HTTPSv.HPath:=ADR('/Storage/'); //Home path (ARM 7)
        HTTPSv.HPath:=ADR('C:/WPages/'); //Home path (Cortex M7)
        HTTPSv.HPath:=ADR('/tmp/'); //Home path (Raspberry)
        HTTPSv.PDefault:=ADR('Home.htm'); //Default page
        HTTPSv.Timeout:=2.0; //Execution timeout (S)
    END_IF;

    // -------------------------------------------------------------------------
    // HTTP SERVER
    // -------------------------------------------------------------------------
    // Manage the server.

    HTTPSv(); //HTTP server
    HTTPSv.RAck:=FALSE; //Request acknowledge
    HTTPSv.RNAck:=FALSE; //Request not acknowledge
    IF NOT(HTTPSv.RRcvd) THEN CaseNr:=0; RETURN; END_IF;

    // -------------------------------------------------------------------------
    // CASES MANAGEMENT
    // -------------------------------------------------------------------------
    // Program management cases.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // Copy to buffers the page and data received on request.
        // This is only to debug purposes.

        0:
        i:=Sysmemmove(ADR(RPage), HTTPSv.pPage, Sysstrlen(HTTPSv.pPage));
        i:=Sysmemmove(ADR(RData), HTTPSv.pRxData, Sysstrlen(HTTPSv.pRxData));

        // Check the page requested by the client.

        IF (SysStrFind(HTTPSv.pPage, ADR('Division.php'), FIND_DEFAULT) = HTTPSv.pPage) THEN CaseNr:=10; RETURN; END_IF;
        HTTPSv.RNAck:=TRUE; //Request not acknowledge
        CaseNr:=0; //Program case

        // ---------------------------------------------------------------------
        // Acquire data sent (GET).

        10:
        Ptr:=SysStrFind(HTTPSv.pRxData, ADR('Dividend='), FIND_GET_END); //Auxiliary pointer
        IF (Ptr = NULL) THEN Error:=10; CaseNr:=100; RETURN; END_IF;
        IF NOT(SysVarsscanf(Ptr, '%f', REAL_TYPE, ADR(Dividend))) THEN Error:=11; CaseNr:=100; RETURN; END_IF;

        Ptr:=SysStrFind(HTTPSv.pRxData, ADR('Divisor='), FIND_GET_END); //Auxiliary pointer
        IF (Ptr = NULL) THEN Error:=20; CaseNr:=100; RETURN; END_IF;
        IF NOT(SysVarsscanf(Ptr, '%f', REAL_TYPE, ADR(Divisor))) THEN Error:=21; CaseNr:=100; RETURN; END_IF;

        Result:=Dividend/Divisor; //Result value

        HTTPSv.TxDSize:=SysVarsnprintf(HTTPSv.pTxData, HTTPSv.HTTPBSize, 'Result=%.3f', REAL_TYPE, ADR(Result));
        HTTPSv.RAck:=TRUE; //Request acknowledge
        CaseNr:=0; //Program case

        // ---------------------------------------------------------------------
        // Arrive on request error.

        100:
        HTTPSv.TxDSize:=SysVarsnprintf(HTTPSv.pTxData, HTTPSv.HTTPBSize, 'Error: %d, on request', USINT_TYPE, ADR(Error));
        HTTPSv.RAck:=TRUE; //Request acknowledge
        CaseNr:=0; //Program case
    END_CASE;

// [End of file]
Home.thm

Ti è stato utile questo articolo ?

Ultimo aggiornamento: 27 Aprile 2020