TCP Socket in web app

La mia web app si collega tramite TCP socket ad un altro programma, il quale fornisce i dati da visualizzare nelle pagine.

L’ aggiornamento dei dati avviene ogni 2 secondi ed i dati inviati sono circa 50 kbyte alla volta.

Il tutto funziona correttamente ma il problema che la CPU viene usata al 30% mentre lo stesso collegamento creato tra due applicazioni desktop utilizzano solo lo 0.1% della CPU.

Perch nella versione web la CPU cos sollecitata ?

Nota: anche dilazionando l’invio dei dati ogni 10 secondi la CPU rimane comunque occupata al 20%

Cosa posso fare per ridurre l’ uso della CPU ?

Come e dove fai avvenire il collegamento tra le due web app?

L’ applicazione desktop fa da server (Listen) mentre la web app fa da client.

Quando una pagina del browser viene aperta, viene stabilita una connessione con il “server” + routine per lo scambio dei dati

I dati ricevuti vengono scomposti e messi in una matrice shared dell’ applicazione fruibile alle altre sessioni che verranno aperte senza creare ulteriori connessioni.

In caso di chiusura della pagina che ha generato il collegamento, le altre pagine aperte si accorgono che la connessione stata interrotta siccome una variabile condivisa ricevuta dal server che il timestamp del messaggio, non viene pi aggiornato azionando il meccanismo di connessione dalle altre pagine aperte.

Quando una delle pagine rimaste aperte riesce a riconnettersi il timestamp verr modificato nuovamente indicando alle altre pagine di cessare i tentativi di connessione.

Note:
La CPU lavora tanto anche con una sola pagina aperta.
Client e server si trovano sullo stesso computer
A gestire le tempistiche di trasmissione e ricezione e di verifica della connessione sono dei timer e non cicli LOOP

Se hai una soluzione meno articolata per avere una connessione TCP con un’ applicazione web sar ben lieto di prenderla in considerazione.

In generale con il profiling del codice puoi avere un’indicazione del tempo speso nelle varie parti del programma.

Provo a dare qualche modesto suggerimento basandomi su quanto ho capito dalla descrizione.

Non e’ chiaro come i timers agiscono sulla trasmissione/ricezione/verifica della trasmissione.
Non e’ necessario un sistema di temporizzazione per la gestione dei socket TCP: opportuni eventi sono generati in base all’attivita’ della comunicazione stessa senza richiedere ulteriori operazioni di polling.

Per quando possibile evita operazioni di polling per rilevare variazioni di stato dell’applicazione.
Esistono dei pattern di programmazione adatti a questo scopo, come ad esempio l’Observer.
In pratica chi gestisce una condizione, come ad esempio la comunicazione, notifica agli interessati le eventuali variazioni di stato.
Trovi negli esempi forniti con Xojo in “Design Patterns\Observer” l’esempio di come implementare questo sistema di notifica.

Se la comunicazione interessa le pagine aperte, rendi la comunicazione un’entita’ autonoma:

  • le pagine si registrano come observers alla comunicazione
  • la comunicazione notifica la ricezione di nuovi valori alle pagine
  • il termine e il ripristino della connessione dipende dalla presenza di pagine (observers) registrate alla comunicazione.

Spero di non aver creato ulteriore confusione.

Saluti.

I consigli di Maurizio sono in generale corretti; non avendo dettagli su chi gestisce la comunicazione e basandosi sulla tua descrizione credo che siano la soluzione al tuo problema.

Siccome riprogetter la mia applicazione da 0 avrei bisogno di alcune dritte per creare ci che necessito, ovvero una connessione TCP costante con il server e l’ applicazione web se possibile anche senza sessioni aperte.
E’ possibile ?

Se si come potrei realizzarlo ? (Attivazione di un thread separato,…)
Se no che alternativa mi suggerireste ?

Al momento sono a corto di idee…

Grazie per qualsiasi suggerimento.

La connessione TCP non ha bisogno di un thread per la gestione: il socket puo’ essere una proprieta’ dell’applicazione quindi indipendente da eventuali sessioni.
L’utilizzo di un thread puo’ essere utile se sono richieste elaborazioni per il protocollo applicativo e la conversione/elaborazione dei dati che possono impiegare tempo.
Il thread ha il vantaggio di essere eseguito in “time sharing” con le eventuali sessioni attive.
E’ quindi necessario valutare le esigenze dell’applicazione e decidere di conseguenza.

In generale gli eventi di base dei sockets sono comunque gestiti a livello di applicazione.
Un eventuale thread puo’ ottimizzare le prestazioni generali dell’applicazioni se esegue delle elaborazioni sui dati trasferiti.

Saluti.

Concordo per l’ utilizzo degli eventi del socket, ma per l’ apertura del socket ho un problema:

Imposto la variabile MySocket come TCPsocket nelle shared variable della web app.

Nell’ evento di avvio creo l’oggetto:

app.MySocket = new TCPSocket

La sintassi corretta ma durante l’ esecuzione un errore mi indica che devo creare una sessione prima di creare l’ oggetto.

Sono obbligato a creare l’ oggetto durante una sessione (Avvio di una pagina) ?

Se cos fosse sarei ancora obbligato ad usare una sessione per trasferire i dati ricevuti nella matrice condivisa dell’ applicazione come avevo fatto in precedenza ed i dati verrebbero attualizzati solo in presenza di finestre aperte.

Dunque,

dichiaro una proprieta’ MySocket (pubblica o privata non importa) di tipo TCPSocket dell’applicazione quindi di App.
Nell’evento Open di App eseguo l’istruzione Mysocket = new TCPSocket.

Nessuna eccezione in Xojo 2015r2.2.

L’eccezione si verifica sulla New o in qualche altro punto?

Il problema nella creazione dell’ oggetto era dovuto al fatto che avevo creato un control container di prova con lo stesso nome TCPSocket.

La possibile causa dell’ enorme utilizzo della cpu credo che sia dovuto al fatto che una web app standalone richieda piu’ risorse della versione desktop, infatti ho inviando dati senza che venissero elaborati il consumo della cpu si aggirava attorno al 3 % mentre
eseguendo la funzione per la divisione dei messaggi ed il calcolo del checksum (CRC16) la CPU andava al 25%.

Penso che le web app non abbiano la stessa potenza d’ elaborazione delle funzioni matematiche parificabili alla versione desktop (giustamente)

Forse il codice eseguito dalla versione web non e’ lo stesso della versione desktop?

L’ultima frase non la capisco…

Infatti, non capisco l’ultima frase

La versione Web/console non ha le funzionalit GUI, presenti ovviamente nella versione Desktop. Le capacit di elaborazione delle funzioni matematiche sono le stesse.
Poniamo che il tuo socket debba ricevere un messaggio, verificare il CRC e poi restituire il suo contenuto se il CRC corretto.
Puoi creare questo oggetto e utilizzarlo indifferentemente sia su una app web che su una desktop (ovvero condividere lo stesso codice Xojo)

Nel senso che il file exe generato per il progetto desktop pi performante rispetto alla versione web siccome richiedendo meno risorse per eseguire le medesime funzioni.

Per quel che riguarda il progetto, ho creato una classe “TCPShared” da usare in entrambi i progetti che ingloba la classe TCPSocket e tutte le funzioni per la creazione della connessione, l’ invio e la ricezione dei messaggi con controllo del checksum ed altre funzioni per gestire il protocollo da me creato.

Ora ho modificato il protocollo e sembra che funzioni molto meglio.

Mi spiego:

Prima inviavo circa 1000 pacchettini con il relativo Checksum, marcatori inizio / fine messaggio / timestamp,…

Ora raggruppo i dati da inviare in un unico messaggio ed in seguito allego il checksum e lo invio.

Con questo accorgimento ora la CPU sollecitata solo all 1 %.

In generale il protocollo TCP non se’ molto efficiente nel trasferimento di pacchetti con pochi dati.
Dal punto di vista del programma l’efficienza del codice del progetto non cambia in base al tipo di target Xojo se il codiuce esegue operazioni indipendenti dal target come, in questo caso, la gestione dei socket.
Come ha suggerito Antonio, la comunicazione e’ un elemento che puo’ essere incapsulato in un oggetto riutilizzabile nei vari target garantendo le stesse prestazioni.

Utilizzo Xojo quasi esclusivamente in applicazioni Web standalone, ovvero senza web server esterno, e per esperienza posso ribadire che le prestazioni dell’applicativo dipendono molto piu’ da come il programma e’ scritto che dal tipo di target (desktop, web…).

Buon lavoro.

Grazie per il supporto che mi avete fornito in questa ed in altre occasioni su questo forum.

Saluti.