Forum: Mikrocontroller und Digitale Elektronik http get: Verbindung jedes Mal neu aufgebaut?


von Harry (Gast)


Lesenswert?

Hallo,

ich habe hier ein Projekt übernommen, bei dem Messdaten aus einem µC an 
ein PC Anwendung übermittelt werden.
Der PC sendet ein Paket mit den gewünschten Daten an den µC und dieser 
antwortet dementsprechend.
Das ganze passiert über einen Webserver im µC. Der PC sendet also einen 
http request, der µC die http response.

Jetzt gibt es in der Anwendung auch eine streaming Funktion mit der 
zyklisch Daten ausgelesen werden können 1s oder langsamer.

In Wireshark ist mir dann aufgefallen, dass bei jeder Message, die 
ausgetauscht wird die Verbindung geöffnet und wieder geschlossen wird.

Ist das ein normales Verhalten?
Kennt jemand ein Sequenzdiagramm welches eine Anfrage an einen webserver 
bis auf TCP Ebene herunter darstellt? Ich konnte (wohl mangels 
Suchbegriffe) nichts geeignetes finden.

In meinen Augen ist ein HTTP Server nicht für solche streaming 
Angelegenheiten geeignet, besser direkt ein TCP Socket. (Nun ja, ist 
aber so umgesetzt und vorhanden.)

Unabhängig von dieser Applikation betrachtet:
Ich kann mir auch vorstellen, dass beobachtetes Verhalten korrekt ist, 
da die Daten ja geliefert wurden und vom internetsurfenden PC User erst 
gelesen werden müssen. Bevor das immer ins Timeout rennt, wird die 
Verbindung direkt geschlossen.

Grüße
Harry

von Εrnst B. (ernst)


Lesenswert?

> Ist das ein normales Verhalten?

Ja.
Suchwort "HTTP Keep-Alive" für Optionen wie das zu umgehen ist, und 
welche Voraussetzungen der Server dafür mitbringen muss.

> In meinen Augen ist ein HTTP Server nicht für solche streaming
> Angelegenheiten geeignet,

Geht schon,
früher per "long-poll" und andere Hacks, heute nimmt man Websockets. Da 
läuft der Verbindungsaufbau auch über HTTP, schaltet dann aber 
zwischendurch auf ein anderes Protokoll und lässt die TCP-Verbindung am 
Leben.

von Harry (Gast)


Lesenswert?

Εrnst B. schrieb:
> Suchwort "HTTP Keep-Alive"

Ah, das scheint genau das zu sein was ich brauche oder besser gleich nur 
TCP.

Εrnst B. schrieb:
> Websockets

Wird beim uC leider nicht mitgeliefert. Da der Webserver sonst keine 
Funktion besitzt, denke ich es ist das beste auf reine TCP Sockets 
umzusteigen. Das schont auch die Ressourcen insgesamt.

Danke für deine Antwort.

von Stefan F. (Gast)


Lesenswert?

Harry schrieb:
> In Wireshark ist mir dann aufgefallen, dass bei jeder Message, die
> ausgetauscht wird die Verbindung geöffnet und wieder geschlossen wird.
> Ist das ein normales Verhalten?

Beim HTTP 1.0 Protokoll muss das so sein. Das Trennen der Verbindung 
kennzeichnet das Ende der Response.

Bei HTPP 1.1 wurde das geändert. Dort kann der Server wahlweise

a) durch einen Content-Length Header die Größe der folgenden Response 
melden, oder
b) Durch einen Chunk der Größe 0 das Ende der Response markieren.

Die Verbindung kann danach offen bleiben und für den nächsten Request 
verwendet werden. Neu seit HTTP 1.1 ist auch, dass der Client mehrere 
Requests direkt hintereinander senden kann, die der Server dann 
nacheinander abarbeitet.

Die Wikipedia verweist auf die Spezifikationen, die ich im groben und 
ganzen verständlich finde. Auf deren Basis habe ich die QtWebApp 
Bibliothek (HTTP Server in C++) geschrieben. Antworten zu Detailfragen 
habe ich überwiegend auf Webseiten von Microsoft gefunden.
https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP/1.0

von Stefan F. (Gast)


Lesenswert?

Harry schrieb:
>> Websockets
> Wird beim uC leider nicht mitgeliefert.

Ist ein Aufsatz auf HTTP. Wenn dein Mikrocontroller eine HTTP 1.1 Server 
Funktion hat, kannst du den Websocket-Aufsatz selbst implementieren. 
Großartig kompliziert sieht das nicht aus, ich hab es allerdings noch 
nicht versucht.

Wenn der Client ein Web-Browser sein soll, hast du kaum eine andere 
Wahl, als Websockets zu verwenden. Für selbst geschriebene Clients ist 
je nach Anwendung TCP oder UDP einfacher. TCP würde ich nur nehmen, wenn 
Lückenlose Übertragung wichtig ist. UDP stellt das nicht sicher, ist 
dafür schneller und überträgt gleichmäßiger (gerät bei Störungen weniger 
ins Stocken).

von Harry (Gast)


Lesenswert?

Auch dir danke für die Antwort.
Ich denke trotzdem, dass ich die ganze Geschichte auf TCP Sockets 
umbauen werde.

Es muss kein Webserver laufen und es muss auch kein ping pong streaming 
stattfinden.

Einmal den Stream starten und dann mit "eigenen keep alive" Paketen 
immer wieder mal "den watchdog resetten".

Das scheint mir sinnvoller. Dann hat man auch die Zeitbasis aus dem uC 
und nicht die vom PC.

von Harry L. (mysth)


Lesenswert?

Harry schrieb:
> In meinen Augen ist ein HTTP Server nicht für solche streaming
> Angelegenheiten geeignet, besser direkt ein TCP Socket. (Nun ja, ist
> aber so umgesetzt und vorhanden.)

MQTT wurde genau für solche Anwendungen erfunden.

von Stefan F. (Gast)


Lesenswert?

Harry L. schrieb:
> MQTT wurde genau für solche Anwendungen erfunden.

Für Streaming? Entweder hast du den Harry nicht verstanden oder ich 
dich.

von Harry L. (mysth)


Lesenswert?

Stefan ⛄ F. schrieb:
> Für Streaming? Entweder hast du den Harry nicht verstanden oder ich
> dich.

Scheint eher, als hättest du nicht richtig gelesen.

Harry schrieb:
> ich habe hier ein Projekt übernommen, bei dem Messdaten aus einem µC an
> ein PC Anwendung übermittelt werden.
> Der PC sendet ein Paket mit den gewünschten Daten an den µC und dieser
> antwortet dementsprechend.

von Harry (Gast)


Lesenswert?

Aber für MQTT brauche ich doch noch einen Broker. Für Cloud-Anwendungen 
ok, aber bei P2P reicht TCP doch völlig. Oder liege ich hier falsch?

von Stefan F. (Gast)


Lesenswert?

Harry schrieb:
> Aber für MQTT brauche ich doch noch einen Broker. Für Cloud-Anwendungen
> ok, aber bei P2P reicht TCP doch völlig. Oder liege ich hier falsch?

Wenn du den PC man neu starten musst (Windows Update), gehen dir ohne 
Zwischenspeicher Daten verloren. Bei einem MQTT Broker hast du das 
Problem nicht, wenn wir mal davon ausgehen dass er auf einer weitgehend 
wartungsfreien Maschine (z.B. unter Linux) läuft. So ein Broker kann 
auch redundant aufgebaut sein.

von Clemens L. (c_l)


Lesenswert?

Harry schrieb:
>> Websockets
>
> Wird beim uC leider nicht mitgeliefert.

Dann nimm SSE (Server-Sent Events). Unidirektional, und sehr einfach 
manuell zu implementieren.

von Stefan F. (Gast)


Lesenswert?

Clemens L. schrieb:
> Dann nimm SSE (Server-Sent Events). Unidirektional, und sehr einfach
> manuell zu implementieren.

Das ist die falsche Übertragungsrichtung.

von S. R. (svenska)


Lesenswert?

Harry schrieb:
> Ist das ein normales Verhalten?

Für HTTP/1.0 ja, für HTTP/1.1 (insbesondere einfachere Implementationen) 
auch.

> In meinen Augen ist ein HTTP Server nicht für solche streaming
> Angelegenheiten geeignet, besser direkt ein TCP Socket. (Nun ja, ist
> aber so umgesetzt und vorhanden.)

HTTP hat den Vorteil, dass es durch sämtliche Firewalls durchgeht, von 
allen Middleware-Boxen unterstützt wird und auch sonst als "das eine 
Protokoll" gesehen wird. Je nach Paranoia der IT-Abteilung wird auch 
schonmal alles andere weggefiltert.

Wenn du schon eine funktionierende HTTP-Lösung hast, würde ich mir erst 
recht überlegen, ob ich davon weggehen wollen würde. Weil du dir damit 
zukünftige Probleme beschaffst.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Weil es noch nicht erwähnt wurde: HTTP/2. Verbessertes Streaming, 
Multiplexing über eine einzige TCP-Verbindung und andere nette Dinge.

: Bearbeitet durch User
von C.K. (Gast)


Lesenswert?

Muss es denn HTTP sein?

Ich habe bisher immer auf µC Seite mit LwIP ein TCP-Server-Socket 
programmiert.

Auf PC-Seite dann eine Anwendung die eine Verbindung aufbaut.
Der µC schickt dann seine Messdaten.

Im einfachsten Fall Zeilenweiße in ASCII codiert.
Hab's aber auch schon Binär gemacht und ein Anwendungsprotokoll dafür 
implementiert.

Verbindung bleibt solange bestehen, bis die PC-Anwendung sie wieder 
schließt.

von Unbekannt U. (Gast)


Lesenswert?

C.K. schrieb:
> Muss es denn HTTP sein?

Was ist daran so schlimm? Weil es Web-Technologie ist?


C.K. schrieb:
> Der µC schickt dann seine Messdaten.
>
> Im einfachsten Fall Zeilenweiße in ASCII codiert.

Also der Server sendet z.B.:

   1,2344 <END_OF_LINE>
   2,1234 <END_OF_LINE>
   3,4234 <END_OF_LINE>
   ....

Sinmples ASCII-Protokoll, so habe ich Dich verstanden.

Und nun, die komplizierte Änderung für den Server, wenn er als 
HTTP-Server fungieren soll, sendet der Server:

  HTTP/1.0 200 OK <END_OF_LINE>
  Content-Type: text/event-stream <END_OF_LINE>
  <END_OF_LINE>
  data: 1,2344 <END_OF_LINE>
  <END_OF_LINE>
  data: 2,1234 <END_OF_LINE>
  <END_OF_LINE>
  data: 3,4234 <END_OF_LINE>
  <END_OF_LINE>
  ...

Und schon hast Du einen HTTP-Server programmiert:

Einmal nach Verbindungsaufbau einen kleinen Header senden, danach vor 
jeden Messwert den String "data:" senden, und die einzelnen Messwerte 
durch Leerzeilen unterteilen.

Fertig sind die Server-Sent-Events!

Plötzlich hast Du alle Vorteile von HTTP:

 - Beinahe grenzenlose Angebot an Tooling
 - Für jeden erdenkliche Programmiersprache gibt es Bibliotheken
   um den Eventstream zu lesen
 - Du kannst Proxies und Reverse-Proxies verwenden
 - und, und, und.

von Harry (Gast)


Lesenswert?

Unbekannt U. schrieb:
> Was ist daran so schlimm? Weil es Web-Technologie ist?

Ich stelle mir vor, dass ein embedded webserver ressourcenhungriger ist 
als ein reiner TCP Socket.

Berichtigt mich bitte, falls der Unterschied vernachlässigbar gering 
ist.

von Stefan F. (Gast)


Lesenswert?

Harry schrieb:
> Ich stelle mir vor, dass ein embedded webserver ressourcenhungriger ist
> als ein reiner TCP Socket.

Kommt ganz drauf an, wie viel du vom HTTP Protokoll implementieren 
willst.

Nach deiner eigenen Aussage willst du, dass der PC (Client) ein Kommando 
sendet und der Server daraufhin antworten liefert. Das ist eigentlich 
genau der Grundgedanke von HTTP. Die einzige Ressource die du dafür 
brauchst ist ein Zeilenpuffer (wohl weniger als 100 Bytes). Du kannst 
sogar ein und den selben Puffer abwechselnd zum Senden als auch zum 
Empfangen benutzen.

Siehe 
http://stefanfrings.de/mikrocontroller_buch/Einstieg%20in%20die%20Elektronik%20mit%20Mikrocontrollern%20-%20Band%202.pdf 
Kapitel 10, dort ist das Protokoll beschrieben, nur die Basics die du 
brauchst.

Klar kannst du auch dein eigenes Protokoll entwickeln, ich bezweifle 
allerdings das es deutlich einfacher wird. Auf jeden Fall wird es 
schwieriger zu testen. Ein Web-Browser zum Testen ist wohl kaum an 
Einfachheit zu toppen.

http://stefanfrings.de/mikrocontroller_buch/Einstieg%20in%20die%20Elektronik%20mit%20Mikrocontrollern%20-%20Band%203.pdf 
Kapitel 13 zeigt, wie man einen einfachen HTTP Server auf einem 
Mikrocontroller implementieren kann.

Auf http://stefanfrings.de/esp8266/index.html#tcpsketch findest du ein 
Arduino Beispiel mit TCP Socket ohne HTTP. Wesentlich einfacher sieht 
das dort nicht aus. Aber entscheide selbst.

von opzuiziziz (Gast)


Lesenswert?

frage wäre wie wichtig die messdaten sind ^^
sonst ginge auch UDP broadcast

einfach einen eigenen header mit einer art sequenznummer und timing 
mitsenden
damit kann ein/mehrere empfänger auch interpolieren wenn er mal was 
verpasst hat

von Clemens L. (c_l)


Lesenswert?

Stefan ⛄ F. schrieb:
>> Dann nimm SSE (Server-Sent Events). Unidirektional, und sehr einfach
>> manuell zu implementieren.
>
> Das ist die falsche Übertragungsrichtung.

Vom Embedded-Webserver an den PC ist die richtige Richtung.

von Stefan F. (Gast)


Lesenswert?

Clemens L. schrieb:
> Vom Embedded-Webserver an den PC ist die richtige Richtung.

Ja, ich dachte bis dahin, dass Harrys µC die Verbindung zum PC aufbauen 
soll, also dann der HTTP Client ist. Aber in seinen folgenden Beiträgen 
wurde klar, dass er es anders herum machen will. Passt schon.

Stefan ⛄ F. schrieb:
> Nach deiner eigenen Aussage willst du, dass der PC (Client) ein Kommando
> sendet und der Server daraufhin antworten liefert. Das ist eigentlich
> genau der Grundgedanke von HTTP.

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.