Live Daten anzeigen

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
Bio Salami
User
Beiträge: 63
Registriert: Mittwoch 28. Juli 2021, 14:10

Hi,
Ich suche nach einem Weg den Text der vom Pi aufgezeichnet wird auf eine Website zu bringen ohne diese die ganze Zeit neu zu laden.
Ich habe bisher eine Seite auf der der Text angezeigt wird und eine mit einem iFrame der sich immer nach 2 Sekunden Updated.
Allerdings verschwindet der Text kurz wenn ein Update durchgeführt wird.

SocetIO wäre eine Lösung aber etwas übertrieben für den Anfang denke ich. Gibt es eine andere Lösung?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es gibt websockets oder server side events. Aber das ist im Grunde Socket.IO. So kompliziert muss es eben werden, wenn man etwas im Hintegrund machen will.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Das einfachste ist ein fetch, das im Hintergrund den Server abfragt und dann den DOM updated. Das sind eine Hand voll javascript-Zeilen, mehr nicht
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@BioSalami,

als Alternative, falls der Raspberry die Daten periodisch zur Verfügung stellt, kannst du auch in gleichmäßigen Abständen vom Browser aus Anfragen per AJAX an den Server senden.
Dann kann es natürlich passieren, dass es bei einer Anfrage noch keine neuen Daten vom Pi gibt. Die Anfragen würden also unnötige Übertragungen hervorrufen.

Das schöne an einer Websocket-Verbindung ist, dass nur Daten bei Bedarf übertragen werden.
Es ist auch nicht sehr kompliziert. Ich hatte hier mal ein ähnliches Beispiel gepostet.
Dies ist eine noch einfachere Version:

Code: Alles auswählen

import asyncio
from datetime import datetime
import uvicorn
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
from starlette.websockets import WebSocketDisconnect
from websockets.exceptions import ConnectionClosedOK

app = FastAPI()

PAGE = """
<!DOCTYPE html>
<html>
    <head>
        <title>Webscoket-Background-Task</title>
    </head>
    <body>
        <div id="clock"></div>

        <script>
            const ws = new WebSocket("ws://localhost:8000/ws");
            const clockElement = document.getElementById('clock')

            ws.onmessage = (event) => {
                clockElement.innerHTML = event.data;
            };

            ws.onopen = () =>{
                ws.send("start")
            }

        </script>
    </body>
</html>
"""

async def get_data():
    await asyncio.sleep(5)
    return datetime.now().strftime("%d.%m.%Y, %H:%M:%S")


@app.get("/")
async def get():
    return HTMLResponse(PAGE)


@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    try:
        await websocket.accept()
        while True:
            await websocket.receive_text()
            while True:
                data = await get_data()
                await websocket.send_text(str(data))
    except (WebSocketDisconnect, ConnectionClosedOK):
        return


if __name__ == "__main__":
    uvicorn.run("__main__:app", host="127.0.0.1", port=8000, ws="auto", log_level="debug")
Zu Demonstrationszwecken ist alles in einer Datei untergebracht. Das macht man in der Realität natürlich anders.
Für den Server verwende ich uvicorn und FastAPI. Das hat den Vorteil, dass die Applikation auch Hintergrundaufgaben ausführen kann, ohne dass etwas blockiert.
Man kann auch auch problemlos mehrere Browserfenster öffnen und in mehreren "gleichzeitig" die Daten vom Server empfangen.

Im konkreten Beispiel sendet der Server alle 5 Sekunden die Uhrzeit an den Browser. Hat man mehrere Browser-Tabs geöffnet verbinden sich alle mit dem Server, bekommen aber dennoch alle 5 Sekunden ihre Antwort vom Server. Es blockiert also nichts. Der Server hält eine eigene Websocket-Verbindung mit jedem Browser-Tab.

Die Funktion 'get_data' muss natürlich nicht die Zeit angeben, sondern kann alles mögliche tun - zum Beispiel die GPIO Pins lesen.
Benutzeravatar
Bio Salami
User
Beiträge: 63
Registriert: Mittwoch 28. Juli 2021, 14:10

Ok. Ich glaube das ich mit Sockets arbeite. Danke!
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Was für einen Server bzw. Webframework verwendest eigentlich auf deinem Raspberry?
Antworten