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
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?
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])
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.
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).
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.
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?
> 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 :)
}
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.
>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...
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.
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
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