Pages: 1 ... 3 4 [5] 6 7 ... 13   Go Down
Author Topic: Websocket [ci siamo quasi]  (Read 12656 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: July 02, 2013, 06:36:29 pm by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
public:
  static uint8_t _is_new[MAX_SOCK_NUM];

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

ciao
Logged

no comment

0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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 ::
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Milan, Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 349
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: July 03, 2013, 03:50:11 am by bigjohnson » Logged


0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bigjonson, noto che non hai seguito una cippa del discorso smiley

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.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Milan, Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 349
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
« Last Edit: July 03, 2013, 04:48:54 am by bigjohnson » Logged


0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: July 03, 2013, 04:50:25 am by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

no comment

0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Milan, Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 349
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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:
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();
  }
}
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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




 
Logged

no comment

0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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


« Last Edit: July 04, 2013, 04:38:17 pm by pablos » Logged

no comment

0
Offline Offline
Shannon Member
****
Karma: 136
Posts: 10525
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Pages: 1 ... 3 4 [5] 6 7 ... 13   Go Up
Jump to: