Forum: Mikrocontroller und Digitale Elektronik technologie für z.B. longpolling


von baer (Gast)


Lesenswert?

Hallo, ich will mit nen Microcontroller (begrenzter Speicherplatz) einen 
kleinen Web-Server betreiben, auf dem auch z.B. Schaltzustände von 
diversen Relays angezeigt werden...

wer nicht viel lesen will schaut einfach den vorletzten absatz an :)

Vom Prinzip soweit nicht schwer.

Die Online Beispiele haben dann oft ein Frame das sich alle X Sekunden 
aktualisiert...
Allerdings dauern mir X Sekunden zu lange... klar könnte ich jetzt den 
Controller mit Requests befeuern z.B. alle 200ms (was ja annähernd 
zufriedenstellend ist), aber auf dauer kostet das irgendwie "UNMENGEN" 
an Energie.

Also habe ich mich mit Socket-Server beschäftigt... vom Prinzip Spricht 
eben wer war zu sagen hat und die Clients/Server hören immer nur zu und 
reagieren sobald jemand was sagt... Leider ist das zusätzlich Hardware, 
weil z.B. ein rPi noch nebenbei laufen muss.

Aber müsste es nicht Theoretisch auch einfacher in einem Microcontroller 
gehen? Reden wir mal nur von einem Relay, ich will den zustand schalten 
und abfragen. Schalten geht "verzögerungslos", auch eine Abfrage läuft 
im unspürbaren bereich... Wenn jetzt allerdings das Relay geschaltet 
wird, dauert es an einem "anderen" Client ziemlich lange bis dieser 
angezeigt wird.

Gibt es eine Möglichkeit z.B. über Longpolling das ganze 
"verzögerungsfrei" erkannt wird? Ich müsste einen Request rausschicken, 
und sobald der Server antwortet, diesen Empfangen und wieder einen neuen 
herausschicken... bis zum empfangen können Stunden vergehen, vom Prinzip 
wurde aber nur ein request verschickt...

Kann mir da jemand helfen oder tipps geben, wie ich das umsetze?
Vielen Dank
Gruß baer

von Jan H. (j_hansen)


Lesenswert?

baer schrieb:
> Gibt es eine Möglichkeit z.B. über Longpolling das ganze
> "verzögerungsfrei" erkannt wird? Ich müsste einen Request rausschicken,
> und sobald der Server antwortet, diesen Empfangen und wieder einen neuen
> herausschicken... bis zum empfangen können Stunden vergehen, vom Prinzip
> wurde aber nur ein request verschickt...
>
> Kann mir da jemand helfen oder tipps geben, wie ich das umsetze?

Genau so? Welche konkreten Fragen hast du denn dazu?

von baer (Gast)


Lesenswert?

eingentlich alles...

ich bin jetzt mit Javascript kein NOOB und ich habe auch schon einen 
Webserver z.B. auf einen Arduino oder einen ESP8266 geflasht...

Ich weiß wie man mit dem Microcontroller einen Request abfragt und 
auswertet...

was ich aber nicht weiß, besonders im bezug auf Long-Polling wie ich 
alle daten für den client zur verfügung stelle, gleichzeitig aber auch 
den server habe...

also brauch ich erstens die javascriptseite:
wie erfrage ich einen Request der nicht nach 10 Sekunden abbricht bzw 
auf 404 läuft
=> das empfangen müsste sich dann automatisch ergeben..

und gleichzeitig die serverseite:
wie antwortet ich im richtigen moment auf den request (oder antwortet 
ich erst wenn es was zu antworten gibt?)
=> also einfach daten auf den "Client" ausspucken dürfte nicht sooo 
schwer sein...

zu Deutsch => mein Hauptproblem ist die Javascriptseite 
(selbstverständlich für Microcontroller [also ledier ohne jquery und 
ählichen, wegen platz])

von Jan H. (j_hansen)


Lesenswert?

baer schrieb:
> also brauch ich erstens die javascriptseite:
> wie erfrage ich einen Request der nicht nach 10 Sekunden abbricht bzw
> auf 404 läuft
> => das empfangen müsste sich dann automatisch ergeben..

Ganz normal: einfach wegschicken. Timeout kann man hochsetzen, und das 
404 würde vom Server kommen, muss also dort "verhindert" werden. Wenn 
sich dann nach Stunden etwas tut, dann kommt der Request mit den 
Antwortdaten zurück, und du kannst im JavaScript in deiner dann 
aufgerufenen Callbackfunktion damit arbeiten. Sollte der Request 
wirklich einmal in den Timeout laufen oder abbrechen, dann einfach 
gleich einen neuen schicken.

> und gleichzeitig die serverseite:
> wie antwortet ich im richtigen moment auf den request (oder antwortet
> ich erst wenn es was zu antworten gibt?)
> => also einfach daten auf den "Client" ausspucken dürfte nicht sooo
> schwer sein...

Du "hältst" den Request, und beantwortest ihn erst, wenn es etwas zu 
antworten gibt. Genau das ist Longpolling.

> zu Deutsch => mein Hauptproblem ist die Javascriptseite
> (selbstverständlich für Microcontroller [also ledier ohne jquery und
> ählichen, wegen platz])

Die ist wohl der einfachere Teil: einfach ganz normal asynchron (JS ist 
ja genau darauf aufgebaut) einen Request wegschicken und die Antwort 
bearbeiten. Da ist überhaupt nichts "besonderes" für Longpolling dabei. 
Für die Seite scheint es einfach, als würde die Antwort vom Server 
länger brauchen.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo baer,

baer schrieb:
> Kann mir da jemand helfen oder tipps geben, wie ich das umsetze?

wenn Du boost.asio auf Deiner Plattform verwenden kannst, dann könntest 
Du https://github.com/TorstenRobitzki/Sioux darauf zum Laufen bekommen. 
Sioux verwendet long polling und ist in C++ geschrieben. (läuft 
beispielsweise hier: https://dungeonpilot.com).

Ansonsten könntest Du aber mindestens den JavaScript-Teil verwenden (der 
Quellcode ist coffee script und muss nach Javascript übersetzt werden; 
sag bescheid und ich schicke Dir das übersetzte JavaScript).

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

baer schrieb:
> zu Deutsch => mein Hauptproblem ist die Javascriptseite
> (selbstverständlich für Microcontroller [also ledier ohne jquery und
> ählichen, wegen platz])

Äh, Du wolltest den Browser doch nicht auf dem Mikrocontroller laufen 
lassen, oder?

Ansonsten läuft jQuery selbstverständlich auf dem Browser und wenn Du 
eine jQuery-Version nimmst, die z.B. bei google gehosted wird, dann 
stehen die Chancen sogar recht gut, dass die eh schon im cache Deines 
Browsers liegt.

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Also ich mach die Aktualisierung der Daten im Browser über JavaScript 
mit einer .json-Datei. Der Code ist auch sehr kurz. jQuery kannst von 
extern importieren. Desweiteren kann man die Aktualisierungsrate in ms 
einstellen.

Wenn ich das richtig verstanden habe, willst du die Zustände über einen 
Webbrowser vom uC abrufen oder?

von baer (Gast)


Lesenswert?

> Ansonsten läuft jQuery selbstverständlich auf dem Browser und wenn Du
> eine jQuery-Version nimmst, die z.B. bei google gehosted wird,...

naja, ich möchte das ganze selbstverständlich autonom haben!

@Torsten Robitzki:
das schau ich mir mal an... allerdings habe ich mir das mir "nur den 
nötigsten" Code erhofft...
Grundsätzlich mag ich Frameworkes... jQuery ist einfach geil, aber die 
schon geschrieben soll das Autonom, Kompakt und Effizient... 
durchsichtiger Code wäre auch noch praktisch (also so das ich ihn 
verstehen kann, jQuery versteh ich nicht, es macht was es soll) ...

> Ganz normal: einfach wegschicken. Timeout kann man hochsetzen, und das
> 404 würde vom Server kommen, muss also dort "verhindert" werden.
sehr gut, das wollte ich hören :) ... jetzt nur noch die Frage:
1. wie setz ich den Timeout hoch (metadaten)?

mein JS könnte dann so aussehen:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/schalter1=1');
xhr.onload = function() {
    if (xhr.status === 200) {
        alert('Schalterzustand: ' + xhr.responseText);
    }
    else {
        alert('Request failed.  Returned status of ' + xhr.status);
    }
};
xhr.send();

mein ESP8266 macht dann:
vorarbeit: request aufslpitten in [key = schalter1] & [val = 1]
zustand vom gpio1 erfragen
if( gpio1 != val ) {
  client.print(val);
} else {
// do nothing :)
}

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

baer schrieb:
> 1. wie setz ich den Timeout hoch (metadaten)?

Nein, Du lässt die Anfrage umbeantwortet, bis ein relativ langes Timeout 
(z.B. 20s abläuft), dann antwortest Du dem Browser, mit irgend etwas, 
das Ihm klar macht, dass sich an den Daten nix geändert hat. Oder Du 
antwortest dem Browser, wenn in der Zwischenzeit eine Änderung auftritt.

So hast Du minimal Latenz bei minimaler Last.

Du must das asynchron denken: Welche Zustände habe ich und welche 
Ereignisse habe ich.

Wenn Du aber eh nur einen Client dran hängen hast und keine Proxies oder 
ähnliches dazwischen sind, dann kannst Du evtl. doch einfach pollen.

von baer (Gast)


Lesenswert?

>Wenn Du aber eh nur einen Client dran hängen hast und keine Proxies oder
>ähnliches dazwischen sind, dann kannst Du evtl. doch einfach pollen.

selbstverständlich habe ich mehrere Clients dran hängen (5-20 Stück). 
Aber wie kann ich das Timeout definieren? Wenn ich nichts einstelle sagt 
mein request nach einigen Sekunden dass er den Server nicht finden 
kann...

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

baer schrieb:

> selbstverständlich habe ich mehrere Clients dran hängen (5-20 Stück).
> Aber wie kann ich das Timeout definieren? Wenn ich nichts einstelle sagt
> mein request nach einigen Sekunden dass er den Server nicht finden
> kann...

Wenn Dein Server die Verbindung nicht nach einigen Sekunden schließt, 
dann bekommst Du auch keine Fehlermeldung. Was für Technologie 
verwendest Du den auf der Server-Seite?

Einfacher wird es evtl., wenn Du Websockets implementierst, dann must Du 
das Timeout nicht implementieren. Du solltest dafür aber so etwas wie 
ein keep alive implementieren, um clients zu erkennen, die nicht mehr da 
sind.

von baer (Gast)


Lesenswert?

okay,

ich habs verstanden... ich hab da einfach zu kompliziert gedacht... ich 
versuch mir da mal was zusammenzubauen...

ich lass euch auch teilhaben, wenns fertig ist!

Danke nochmals

von S. R. (svenska)


Angehängte Dateien:

Lesenswert?

Ich glaube, was du suchst, nennt sich "Server-Sent Events". Das habe ich 
vor längerer Zeit mal ausprobiert und hier angehängt.

Die HTML-Seite sagt dem Browser, er möge bitte '/events.pl' nach Daten 
fragen. Wenn diese URL (normal per HTTP) antwortet, dann wird im Browser 
ein Event ausgelöst und die Anzeige aktualisiert. Der Server kann die 
Anfrage aber auch hängen lassen, bis ein Timeout feuert. Der Browser 
wird dann automatisch eine neue Anfrage senden.

Genaueres findest du z.B. hier: 
http://www.html5rocks.com/en/tutorials/eventsource/basics/?redirect_from_locale=de

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.