Go Down

Topic: Websocket [ci siamo quasi] (Read 14865 times) previous topic - next topic

lesto

#60
Jul 03, 2013, 01:34 am Last Edit: Jul 03, 2013, 01:36 am by lesto Reason: 1
cavoli buggone!! in ethernetserver.CPP prima di if(onConnect) metti _is_new[client.getId()] = false;
in questp modo onConnect dovrebbe essere chiamato solo la prima volta, se no va aggiunto sempre lì un if chè controlli che la variabile sia true
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos


cavoli buggone!! in ethernetserver.CPP prima di if(onConnect) metti _is_new[client.getId()] = false;
in questp modo onConnect dovrebbe essere chiamato solo la prima volta, se no va aggiunto sempre lì un if chè controlli che la variabile sia true


ok ... ho visto che l'hai dichiarato nella ethernet.h
Code: [Select]
public:
 static uint8_t _is_new[MAX_SOCK_NUM];


ma non lo vede _is_new' was not declared in this scope ... why?

ciao
no comment

lesto

scuuuusa colpa mia, ero da cellulare.. la forma corretta è

Code: [Select]
EthernetClass::_is_new[sock] = false;

_is_new è un array STATICO, ciò vuol dire che non serve inizializzare un oggetto dalla classe: se inizializzi più oggetti vedresti che _is_new è lo stesso e sharato,. In questo caso, visto che l'oggetto non è stata inizializzata e quindi non puoi fare "classe._is_new", allora si usa il nome dellqa classe seguito dai ::
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

#63
Jul 03, 2013, 10:31 am Last Edit: Jul 03, 2013, 10:50 am by bigjohnson Reason: 1
Le connessioni tcp/ip multiple (in ingresso, arduino è il server, e penso anche in uscita) si possono fare, vedi esempio chat telnet, il problema di solito sono le librerie webserver e altro varie che gestiscono una sola connessione alla volta, dall'inizio alla fine e poi passano alla successiva, sono tutte bloccanti sui socket, in quanto attualmente se non attendi la chiusura del socket prima di vedere se ce ne è uno nuovo che invia dati quando ricevi i dati non sai da quale socket li stai ricevendo.

lesto

bigjonson, noto che non hai seguito una cippa del discorso :)

Il probelma non è accettare più EthernetClient, ma IDENTIFICARLI UNIVOCAMENTE.

Se noti tutti gli esempi della Ethernet, o scrivono la stessa cosa a tutti i client connessi, oppure ogni client viene accettato, comunicato qualcosa e poi chiuso.
Però queste librerie:
1. hanno bisogno di un inizializzazione alla connessione, cosa che rende la comunicazione NON uguale tra tutti i client
2. se chiudono la comunicazione ad ogni richiesta perdono di significato, visto che i WebSocket nascono proprio per evitare di ciudere la connessione ogni volta

Se conosci un modo usando la libreria Ethernet attuale prego mostramelo perchè vorrebbe dire che sto facendo fatica inutile per nulla.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

#65
Jul 03, 2013, 11:18 am Last Edit: Jul 03, 2013, 11:48 am by bigjohnson Reason: 1
Caro Lesto, è vero che attualmente il limite di tutte le librerie è dovuto all'implementazione della Ethernet, ho avuto lo stesso problema nell'ardupower, dove devo tenere aperta una connessione telnet al primo client che si autentica e sbattere fuori con un messaggio tutti quelli che si connettono mentre la sessione del primo è ancora attiva, quando la sessione che occupa l'arduino termina devo anche riuscire ad accettare un'eventuale nuova connessione.
Io ho fatto così:

  • Aggiunto al socket una funzione che mi restituisce il numero (da 0 a 4).

  • Ricevo la connessione.

  • Mi salvo il numero del socket.

  • Mi salvo il socket.

  • Controllo che il socket salvato sia sempre aperto, se è chiuso ripristino la sessione se è aperto continuo a ricevere i dati.

  • Continuo a ricevere dati dai vari socket e uso solo quelli che corrispondono al socket che mi interessa, se ricevo connessioni da altri socket le chiudo dopo avere inviato un messaggio.

  • Mi lavoro le stringhe ricevute.


Per realizzare un server websocket purtroppo bisogna fare una cosa simile, e sempre purtroppo si può ascoltare solo un client alla volta, se lo si fa veramente bene se ne possono servire 4 di client ma la vedo difficile non so se basta la memoria.
Se poi insieme al websocket si devono inviare le pagine tramite un webserver normale, bisogna modificare anche tutto il webserver per evitare che monopolizzi i socket....

Per gestire i websocket ci vogliono risorse:

  • socket per gestire le connessioni, e la wiz ne ha solo 4

  • memoria per gestire le sessioni, e l'arduino ne ha poca



Pablos mi aveva già proposto di modificare il wjsonduino con i websocket, ma la vedo difficile, l'approccio pooling è più adatto alla piattaforma:

  • Apro il socket, leggo i dati, magari li scrivo pure, e chiudo il socket rapidamente.

  • Sono pronto a servire altri client.



Con la Due cambia tutto, ma bisognerà pestellare parecchio sulla tastiera per modificare tutte le librerie!

lesto

#66
Jul 03, 2013, 11:46 am Last Edit: Jul 03, 2013, 11:50 am by lesto Reason: 1
Quote
Aggiunto al socket una funzione che mi restituisce il numero (da 0 a 4)

cosa che ho aggiunto anche io. E per evitare casini con connessioni/disocnnessioni ho aggiunto le chiamate di Callback onConnect e onDisconnect. Sempre che per socket intendi EthernetClient

Quote
Mi salvo il socket.

Se intendi EthernetClient non ce nè bisogno, puoi crearlo ogni volta che vuoi a partire dal semplice numero id. è così che fa la libreria EthernetServer ogni richiesta available(), quindi è un metodo "sicuro". Sprechi CPU ma risparmi un sacco di RAM

Quote
e sempre purtroppo si può ascoltare solo un client alla volta

lato arduino leggi un client alla volta (esattamente come farebbe un "normale" PC con server HTTP single-core e single-cpu), ma è il wiznet che si smazza il parallelismo mettendo i dati ricevuto nel giusto buffer. Quindi l'importante è che arduino risca a smazzare i dati abbastanza in fretta da evitare problemi con i buffer... classici problemi che avresti anche con la seriale.

Quote
bisogna modificare anche tutto il webserver per evitare che monopolizzi i socket

il webserver usa 1 socket fisso in ascolto; se uno degli altri 3 socket è libero controlla se è una richiesta WebSocket attiva la libreria, se no risponde con la pagina HTML, altrimenti se nessun socket è libero risponde con una pagina di errore o disconnette uno dei client. Non vedo come possa "monopolizzare" gli altri socket. Certo uno gli va dedicato. Eventualmente anche un secondo per rispondere "picche", il che ci porta a 2 utenti simultanei al massimo.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos

in teoria 3 utenti, il 4° sochet libero ti darebbe la pagina html per poi chiudendersi restando libero per i dati socket, ma 2 bastano utenti bastano e avanzano
no comment

lesto

uhmm non credo, il socket in ascolto ritorna un secondo socket con la connessione, ma il socket principale rimane in ascolto. Altrimenti mentre accetti un socket non potresti accettarne un secondo finchè non lo chiudi
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Se esaurisci i 4 socket quando tenti la connessione con telnet ti rimbalza immediatamente. Per cui il socket del server non risponde più. Nella documentazione della wiz ci sarà scritto come rimbalza il client.

lesto

Code: [Select]
Nella documentazione della wiz ci sarà scritto come rimbalza il client.
ok, sarebbe da fare quelche test, per esempio col codice che c'è ora (allego funzione corretta), vedere cosa succede

codice corretto:

Code: [Select]
void EthernetServer::accept()
{
  int listening = 0;

  for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
    EthernetClient client(sock);

    if (EthernetClass::_server_port[sock] == _port) {
      if (client.status() == SnSR::LISTEN) {
        listening = 1;
      }
      else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
        client.stop();
      }else{
    EthernetClass::_is_new[sock] = false;
if ( onConnect ){
onConnect(client);
}
  }
    }
  }

  if (!listening) {
    begin();
  }
}
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos

C'è un problema,

Quando i sochet sono connessi è sufficiente disconnettere il primo dei 2 o 3 o 4 client collegati che mi cadono tutte le connessioni
mentre se disconnetto es: il 2-4-3 e lascio il primo socket per ultima disconnessione va bene escono dalla connessione regolarmente

ciao




no comment

lesto

immagino che il socket 1 sia quello che è in listening... in tal caso è un comportamento accettabile, essendo il socket reale (ci può essere un solo socket per porta) che contine i socket virtuali (gli EthernetClient accettati)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos

#73
Jul 04, 2013, 09:52 pm Last Edit: Jul 04, 2013, 11:38 pm by pablos Reason: 1

immagino che il socket 1 sia quello che è in listening... in tal caso è un comportamento accettabile, essendo il socket reale (ci può essere un solo socket per porta) che contine i socket virtuali (gli EthernetClient accettati)

E no che non è accettabile, ti pare che 2 o 3 utenti si collegano e il primo chiude prima degli altri e li butta fuori? non va bene  :smiley-eek:

Allora come dissi nei primi post facciamogli assegnare una porta sequenziale automaticamente 9990+_sock in questo caso è ancora virtuale?

ciao


no comment

lesto

no attento, io parlo del socket che resta in ascolto, quello assegnatoi agli utenti sono quelli virtiuali. Puoi fare un test printando gli id sei glient che disconnetti e dei client connessi?
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up