Ankündigung

Einklappen
Keine Ankündigung bisher.

Progressive Web Application. Konzeptfragen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Progressive Web Application. Konzeptfragen

    Hi,

    Ich muss eine neue App schreibe und diese muss auch Offline Fähigkeiten haben. Bevor ich nun anfange da ganz oldschool eine JAVA-Client-App zu schreiben, dachte ich ich schau mir mal PWA an ob das vielleicht auch geht.
    Ich habe mich da nun etwas eingelesen, habe aber noch ein paar Fragen, ob sich das Konzept für meine App überhaupt einsetzen läßt bevor ich anfange und später feststelle, dass ich in eine Sackgasse programmier habe.

    Die App ist eigentlich relativ einfach. Es handelt sich um eine Datenbank auf einem Firmen internen Server, die einige tausend Systeme beinhaltet, wobei jedes System wieder hunderte von Informationen beinhaltet.
    Die Informationen brauchen unsere Techniker, wenn sie an einem System eine Wartung oder Reparatur durchführen. Dabei brauchen Sie natürlich nicht alle Systeme sondern nur die, für die sie zuständig sind. Das sind dann vielleicht so um die 20-30 Stück.

    Gehen wir jetzt mal von einer reinen Online-App aus, dann würde diese folgende Funktionen benötigen:

    1) Authentifizierung durch den Techniker (I.d.R ein SSO Login kann in diesem speziellen Fall aber auch einfacher gestaltet werden)
    2) Der Techniker sucht sich einmalig "seine" Systeme und markiert sie als Favoriten.
    3) Der Techniker muss die Daten dieser Systeme auch pflegen. Sprich, wenn er eine FMI gemacht hat. muss das in die Datenbank eingetragen werden. Ebenso alle anderen Änderungen, wie wenn sich z.B. Kontaktpersonen geändert haben etc etc.

    Das Problem ist nun, dass dort wo die Systeme stehen zu 90% kein Internet zur Verfügung steht. Weder in Form von WLAN noch in Form von Mobilen Netzen.

    Das Ziel wäre jetzt also quasi, dass wenn der Techniker ein System als Favoriten markiert, dieses direkt auf seinen Rechner lokal übertragen wird, so dass er es offline ansehen UND bearbeiten kann. Sobald der Rechner wieder online geht, sollten die modifizierten Daten dann auf dem Server ebenfalls aktualisiert werden.
    Funktioniert das so mit PWA?
    Wie ist das mit der Authentifizierung? Müßte ich dann selber testen ob der Rechner offline ist und wenn ja, dann einfach auf eine Authentifizierung verzichten weil er ja eh nur seine lokalen Daten zur Verfügung hat? Was ist wenn er mittendrin wieder online geht? Bekomme ich das mit und muss dann in den Login-Screen wechseln damit er sich authentifiziert um dann den Sync mit dem Server durchzuführen? Wie funktioniert das?

    Wer kann mir hier helfen ein wenig Licht ins Dunkel zu bringen?

    Danke

    Claus
    Pre-Coffee-Posts sind mit Vorsicht zu geniessen!


  • #2
    Ich denke das lässt sich als PWA umsetzen. Habe mal etwas ähnliches umgesetzt.

    1) Login:
    Nutze am besten ein JWT Token, so lange dieser gültig ist, kannst du den Benutzer eingeloggt haben. Sollte wieder eine Internetverbindung bestehen, kannst du mit einem gespeicherten Refresh Token ein neuen Access Token mit neuer Gültigkeit Abfragen.
    Hier (https://jwt.io/) findest du eine ganze Reihe an Libs für verschiedene Programmiersprachen

    2) Datenbank
    Hier würde ich die IndexedDB des Browser verwenden. Es gibt auch hier viele Libs welche du verwenden kannst.
    https://dexie.org/

    3) Synchronisierung
    Ich würde API Calls immer erst versuchen an den Server zu schicken und sollte keine Internetverbindung bestehen, die Daten aus der IndexedDB laden. Update / Insert API Calls, kannst du in einem Pool Sammeln und sobald eine online Verbindung besteht, diese dann absetzen. Hierfür könnte sich ein Web (Background) Workertask lohnen. .
    https://www.html5rocks.com/de/tutorials/workers/basics/

    Kommentar


    • #3
      Hallo,

      danke für das Feedback. Dexie und Serviceworker hatte ich mir schon als beste Optionen rausgesucht. Aber nur durch lesen weiß man natürlich nie ob man dann beim umsetzen nicht doch noch irgendwelche fallstricke findet. Deshalb hier die Frage. Das mit dem ist Token werde ich mir mal ansehen

      Gruß

      Claus
      Pre-Coffee-Posts sind mit Vorsicht zu geniessen!

      Kommentar


      • #4
        So,

        ich habe jetzt mal ein wenig praktisch damit herumgespielt und eine ganz kleine Testapp geschrieben. Das mit dem ServiceWorker funktioniert auch super.

        PHP-Code:
        /* request is being made */  
        self.addEventListener('fetch', function(event)
        {    
            
        event.respondWith(        
                
        //first try to run the request normally        
                
        fetch(event.request).then(function(response)        
               {
                    
        console.log("Online Request");
                    
        console.log(response);
                    return 
        caches.open(RUNTIME).then(cache =>
                    {
                        
        // Put a copy of the response in the runtime cache.
                        
        return cache.put(event.requestresponse.clone()).then(() =>
                        {
                            return 
        response;
                        });
                    });
                }).catch(function()
                {
                    
        console.log("Catch Offline Request");
                    
        console.log(event);
                    return 
        caches.match(event.request).then(function(response)
                   {
                        
        // Cache hit - return response
                        
        if (response) {
                            return 
        response;
                       }
                       else
                            return new 
        Response("Network error happened", {"status" 408"headers" : {"Content-Type" "text/plain"}});
                    });
                })
            );
        }); 
        Der worker versucht nun immer erst online Daten zu bekommen und wenn er sie bekommt packt er sie direkt in den Cache. Wenn er keine bekommt versucht er sie aus dem Cache zu lesen und wenn das nicht klappt gibt es einen Error (Das mit dem Error muss man dann natürlich noch schöner verpacken)

        Jetzt habe ich ein input Feld gemacht, dessen Inhalt ich mir per AJAX Request aus einer Datenbank hole. Ich kann den Text ändern und mit Hilfe eines Buttons wieder mit einem AJAX Request in die Datenbank speichern.
        Nun stehe ich etwas auf dem Schlauch.
        Ich muss ja theoretisch im Worker erkennen wenn eine Anfrage eine Datenbank-Anfrage ist und dann entsprechend beim lesen (wenn online) in eine IndexedDB speichern und wenn er offline ist dort herausholen, bzw dort hinein updaten.
        Zusätzlich muss ich dann immer wenn der Browser wieder online ist, die IndexedDB irgendwie mit der DB auf dem Server synchronisieren.
        Hier fehlt mir gerade irgendwie der Ansatz.

        Gruß

        Claus
        Pre-Coffee-Posts sind mit Vorsicht zu geniessen!

        Kommentar


        • #5
          Du kannst die Offline Requests ja auch in deinem Cache Speichern und sobald du wieder online bist diese dann sequenziell ausführen. Als Tipp noch, ich würde bei jedem Eintrag in der DB ein "lastUpdate" Spalte einfügen und diese Serverseitig dann abgleichen. So kannst du verhindern, dass wenn z.B. ein Browser 2 Wochen offline war, neuere Daten wieder mit alten Daten überschreibt.

          Kommentar


          • #6
            Zitat von Zeichen32 Beitrag anzeigen
            Du kannst die Offline Requests ja auch in deinem Cache Speichern und sobald du wieder online bist diese dann sequenziell ausführen. Als Tipp noch, ich würde bei jedem Eintrag in der DB ein "lastUpdate" Spalte einfügen und diese Serverseitig dann abgleichen. So kannst du verhindern, dass wenn z.B. ein Browser 2 Wochen offline war, neuere Daten wieder mit alten Daten überschreibt.
            Die Requests sequential zu speichern und abzuarbeiten ist keine optimale Lösung. Ich würde hergehen und immer den kompletten Datensatz lesen und zu schreiben. Das würde dann bedeuten, wenn der User 5 Änderungen vornimmt würde 5x der ganze Datensatz von mehreren MB geschrieben. Da läuft dann auch viel zu schnell der Cache voll. Die Datensätze nur partiell zu lesen und zu schreiben ist recht fehleranfällig und man hat u.U. komplett verschiedene Versionen eines Systems auf Server und Client.

            Das mit dem lastUpdate findest du in jeder meiner Datenbank-Tabellen. Das ist glaube ich eines der ersten Dinge die man lernt.

            Mein Problem ist halt mehr, nehmen wir an, ich würde jetzt hergehen und alle Requests deren URL an den REST Service des Servers geht nicht im cache sondern in der indexedDB speichern. Das wäre recht einfach machbar. Wie aber bekomme ich jetzt mit, dass der ServiceWorker wieder online ist damit ich dann eine Routine starten kann, welche, je nach lastupdate, eben die beiden Datenbanken wieder syncronisiert?

            Gruß

            Claus
            Pre-Coffee-Posts sind mit Vorsicht zu geniessen!

            Kommentar


            • #7
              Wirklich sicher sein, ob eine Online Verbindung besteht, kannst du nur in dem du in bestimmten Intervallen einen Request absetzt und schaust ob dieser durch geht.
              Die Browser eigenen Funktionen wie window.ononline und window.onoffline (https://developer.mozilla.org/de/doc...rOnLine/onLine) können nur erkennen ob generell eine Verbindung besteht. Also ob du z.B. mit einem Wlan Verbunden bist, nicht aber ob auch eine Internet Verbindung besteht.

              Die Requests sequential zu speichern und abzuarbeiten ist keine optimale Lösung. Ich würde hergehen und immer den kompletten Datensatz lesen und zu schreiben
              Wie genau du es umsetzt ist dir ja überlassen und ist sicher Abhängig vom jeweiligen Anwendungsfall. In meinem Anwendungsfall war es wichtig, die Requests in der Reihenfolge abzuarbeiten, wie sie angestoßen wurden.

              Kommentar


              • #8
                Irgendwie ja schon dämlich das es in dem ServiceWorker keinen Event für Online/Offline gibt. Würde die Sache doch irgendwie deutlich schicker machen.

                Trotzdem Danke

                Claus
                Pre-Coffee-Posts sind mit Vorsicht zu geniessen!

                Kommentar


                • #9
                  Sicher wäre so etwas gut. Allerdings würde Online ja dann auch nicht bedeuten das dein Server erreichbar ist.

                  Kommentar

                  Lädt...
                  X