[Arduino Yun] Come cambiare porta al webserver usando YunServer e YunClient ?

Premetto che con Linux sono praticamente a zero e quindi ... magari basta una banale modifica ad un file di configurazione che io non conosco, comunque ...

... ho visto, guardando un po' gli esempi, che, usando YunServer e YunClient, basta inviare da browser la richiesta :

http://ip_arduino/arduino/mio_testo

che la parte "mio_testo" arriva già bella pulita, senza tutti i fronzoli HTTP al mio programma attraverso un semplice ciclo client.read() e la risposta può essere, altrettanto semplicemente, inviata con un banale client.print("mia_risposta"). :slight_smile:

Ora, chiaramente, la suddetta richiesta viene inviata dal browser utilizzando la porta standard HTTP 80 ...
... la mia necessità è di utilizzare un'altra porta, es. 8080 :slight_smile:

Premetto che ho già visto che è possibile, in fase di istanza della classe YunServer scrivere :

YunServer mioServer(8080);

... ovvero indicargli la porta e la cosa, per la parte server, funziona ma purtroppo ... non funziona la parte della risposta del client, ovvero anche se la client.print() viene eseguita, sul browser arriva solo una pagina bianca ... come se la parte YunClient non sia stata informata della porta da usare.

Spero che il problema sia chiaro ... e il succo della domanda è quindi :

Usando le semplici due classi YunServer e YunClient, come fare per poter usare da browser un porta diversa dalla standard per inviare le richieste e ricevere le risposte (es. http: // ip_arduino:8080 / arduino / mio_testo) ?

Grazie.

Guglielmo

se tu metti

YunServer mioServer(8080);

arduino lo chiamerai con

http://ip_arduino:8080/arduino/mio_testo

se ometti di scrivere la porta nella chiamata http://......... per default viene applicata la 80
non dovrebbe essere diverso da altri webserver ...
nel caso di risposta dovrai informare il router di reindirizzare i dati provenienti dalla porta 8080 sull IP di arduino

ciao

Pablos,
forse non sono stato chiaro ... :roll_eyes: ... ma se rileggi tutto il mio post, vedrai che è quello che ho fatto, però ...

... mentre alla parte YunServer basta che nell'istanza passi la porta, la parte YunClient sembra non accorgersene e NON invia la risposta sulla stessa porta, quindi la domanda è ... come configurare YunServer e YunClient in modo che usino un altra porta ?

Guglielmo

Nel codice non vedo nessun passaggio di porta nel Client, eccetto per il connect.
--> https://github.com/arduino/Arduino/blob/ide-1.5.x/libraries/Bridge/src/YunClient.h

Come accade per la libreria Ethernet anche qui i client non sono univoci non avendo parametri che li caratterizzano.

Difatti Paolo,
avevo guardato anche io il sorgente e ... mentre nella YunServer avevo chiaramente trovato il parametro per passare il "port" ... non riesco a capire come fare per rispondere dalla YunClient.

Prendendo come riferimento l'esempio "TemperatureWebPanel" si vede che il meccanismo d'uso delle due classi è veramente semplice ...

...
YunServer server;
...
YunClient client = server.accept();
...
if (client) {
    // read the command
    String command = client.readString();
...
 client.print("
Current temperature: ");
 client.print(temperature);
...

... e funziona perfettamente se non si cambia porta (ovvero si usa port 80 che è il default per il WebServer), ma, se si mette nella dichiarazione del server :

YunServer server(8080);

la parte di ricezione della richiesta dal browser sulla nuova porta arriva correttamente, mentre la risposta data dalla client.print() no :frowning: :frowning: :frowning:

Guglielmo

Allora butta la yun è una ciofeca di scheda ]:smiley: ]:smiley: ]:smiley:
a parte scherzi sembra che per default ci sia la porta 5555 nella yunserver.h

class YunServer : public Server {
  public:
    // Constructor with a user provided BridgeClass instance
    YunServer(uint16_t port = 5555, BridgeClass &_b = Bridge);

le lib sono molto diverse dalla ethernet shield e non avendo la yun tra le mani per fare esperimenti è difficile

cercando un po' ho trovato questo

To listen to commands from connected clients, you need to start the server by calling “server.begin()”. “server.listenOnLocalhost()” forwards all local server communication to port 5555. Process allows you to call Linux commands through your sketch. Here, you’ll execute the shell command “date” by calling “startTime.runShellCommand(“date”)”, which will report the date and time the sketch started running.

fonte: Hands on: the Arduino Yún's Bridge | Arduino Blog

pablos:
Allora butta la yun è una ciofeca di scheda ]:smiley: ]:smiley: ]:smiley:

Mah ... sai che invece la sto apprezzando ... XD

E' che, indubbiamente, per sfruttare appieno alcune cose occorre conoscere bene Linux e ... mi manca XD :grin: XD

Guglielmo

ho modificato il post precedente rileggilo :slight_smile: eri off-line

Grazie Pablos, capisco che senza scheda è molto difficile riuscire a trovare una soluzione ... :roll_eyes:

La porta 5555 sembrerebbe usata "internamente" mentre, verso il mondo esterno, il webserver che gira nella parte Linux, parla HTTP sulla porta standard 80, tanto è vero che di base tutto funziona e con un qualsiasi browser, senza specificare nulla, accedi e ricevi le risposte :slight_smile:

Se invece istanzi la classe YunServer così :

YunServer server(port);

accetti il protocollo HTTP invece che su port 80, sul "port" che specifichi e, provando, in effetti i dati arrivano, peccato poi che con la client.print() non riesci a rispondere e, sul browser, come risposta, ricevi sempre una pagina vuota :frowning:

Guglielmo

Ma non è che c'è un firewall dietro? Non è che la Linino, per motivi di sicurezza, è abilitata a parlare solo sulla 80?
Ho letto in giro che dovrebbe avercelo abilitato di default. mi pare che sia basato su iptables.

Leo, se anche fosse, mi spieghi allora a cosa serve aver previsto la sintassi :

YunServer server(port);

che permettere la ricezione corretta di quello che si manda a :

http://ip_arduino:port/arduino/testo

... ovvero con la client.read() leggi la parola "testo" (provato e funziona) e poi però ... con la client.print() non puoi rispondere ??? :drooling_face: :~ :drooling_face:

Guglielmo

Faccio un'ipotesi, non so come funzioni la Yun. Però i firewall funzionano sia in ingresso che in uscita.

Mi spiace ci ho provato... risolvi al più presto perchè se no mi tocca comprare la yun e sbatterci la testa :smiley: :smiley: :smiley:

Ho trovato questo:
http://tavendo.com/blog/post/arduino-yun-with-autobahn/

qui parlano di un progetto basato sulla Yun che dovrebbe creare una comunicazione bidirezionale e accennano all aporta 8080. Non ho analizzato assolutamente il codice perché esula dalle mie conoscenze, però forse potrebbe aiutarti a capire meglio come risolvere il tuo problema.

scusa puoi provare questo?

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
 
#define PORT 6666
YunServer server(PORT);
 
void setup() {
  Serial.begin(115200);
  Bridge.begin();
  server.noListenOnLocalhost();
  server.begin();
}

	
void loop() {
  YunClient client = server.accept();
 
  if(client.connected()){
    String question = "What is your name?\n";
    client.write((uint8_t*)&question[0], question.length());
     
    String response;
    while(client.connected()){
      if(client.available()){
        char cmd = client.read();
        if(cmd == '\n'){
          break;
        } else {
          response += String(cmd);
        }
      }
    }
    response = "Bye "+response+"\n";
    client.write((uint8_t*)&response[0], response.length());
     
    client.stop();
  }
 
  delay(1000);
}

chiamandolo con l'apposita porta ... ho quasi l'impressione che sia il tuo client che rifiuta i messaggi diciamo "non autorizzati"

Grazie Leo,
... si, di progetti "complessi" che usano direttamente "websocket", "python", ecc. ne ho visti tanti, ma ... è esattamente quello che voglio evitare.

Fate cortesemnete riferimento all'esempio che arriva con la libreria "bridge" e che è visibile qui : TemperatureWebPanel ...

Se date un occhiata al codice a fondo pagina, capite quanto è banale l'uso base delle due classi YunServer e YunClient ...
... tutto di riduce a leggere solo una stringa (già ripulita da tutto l'overhead HTML) e sriverne un'altra con la client.print().

Il bello è che, nonostante il codice banale, il tutto funziona molto bene XD però ... su port 80 :drooling_face:

Se, come dicevo, si cerca di cambiare port, con una sintassi che è prevista, non si sa più come rispondere con le client.print() :frowning:

Guglielmo

pablos:
scusa puoi provare questo?

Il mio codice di prova è molto simile ... non uso la classe String per le strighe, uso dei char array, ma, per il resto della struttura .. mi sembra uguale.

Comunque, domani mattina lo carico e ti faccio sapere :wink:

Grazie.

Guglielmo

@ pablos: prova effettuata ... non so dove tu abbi atrovato quel codice, ma ... funziona peggio del mio ... :roll_eyes:

Con il mio, come detto, arrivo a ricevere la richiesta del browser, che, ripeto, viene accettata nella forma :

http://ip_arduino:port/arduino/messaggio

ma non riesco a rispondere, con il tuo, facendo :

http://ip_arduino:6666/arduino/

... ricevo errore dal browser che mi dice che non riesce a connettersi. Nota bene che, se levo il port 6666 ricevo invece di ritorno il messaggio :

Could not connect to YunServer 146 Connection refused

... quindi, la board stà girando, ma il tuo codice si comporta, purtroppo, peggio del mio =( =( =(

Guglielmo

Non hai risolto?

No Paolo ... ma, per i miei scopi, comunque userò un "detour" ... XD

Programmo il router a fare port-forwarding del "IP-Mio:port_specifico" ---> "IP-Yun:80" ... almeno tutto quello che all'esterno indirizzo a quella porta finisce dritto sulla Yun :wink:

Guglielmo