Hogyan állíthat be alapvető webes értesítési funkciókat egy Flask háttérrendszer segítségével

A webböngészők az elmúlt években egyre erőteljesebbé váltak. Számos olyan szolgáltatás, amelyet korábban csak a mobil alkalmazások kínáltak, már elérhető az interneten is. Ennek oka elsősorban a Google beruházásai a Chrome böngészőbe (és a Mozilla Firefox-on végzett munkája is) és néhány kapcsolódó technológiának, például a Progressive Web Appsnek

A szervizmunkások a technológia központi eleme, amely lehetővé tette a PWA-k számára, hogy versenyezzenek a natív alkalmazásokkal a kínált funkcionalitás szempontjából. A google által létrehozott oktatóanyagból és az MDN-cikkből bevezetést kaphat ezeknek a szolgáltatóknak a működése. Mint az említett cikkekben említésre került, a szolgáltató dolgozók csomó nagyszerű dolgot csinálhatnak, például

  1. Végezzen el egy műveletet, amelynek beszélnie kell a háttérben lévő kiszolgálóval - ezzel eltávolítva a bosszantó betöltő spinnereket
  2. Hálózati proxyként működik - gyorsítótárazza a webhelyhez szükséges különböző eszközöket, és lehetővé teszi egy alaphelyzet betöltését hálózati kapcsolat nélkül is
  3. Fogadjon push értesítéseket a szerverről, és megjelenítse azokat a felhasználó számára.

Ebben a bejegyzésben csak az utoljára említett funkcióra - a webes push értesítésekre - fogunk ragaszkodni. Könnyű támogatást hozzáadni ehhez a harmadik fél eszközének, például a WebEngage, a OneSignal, a Clevertap stb. Integrálásával.

Noha ezek a harmadik féltől származó eszközök a legtöbb célra elegendőek, ha a felhasználói élmény jelentős részeként szándékozunk beilleszteni a push értesítéseket, akkor érdemes ezeket magunk is megvalósítani. A Google webes alaptanfolyamának itt található részletes bemutatója a témáról. Van egy codelabs projekt is, amely demonstrációs projektet biztosít, amely klónozható és kipróbálható. És akkor van ez a Web Push Book, amely valószínűleg a legelterjedtebb bemutató a témához.

Noha ezek az oktatóanyagok meglehetősen részletesek, szükség van egy lépésről lépésre történő oktatóprogramra is, amely a semmiből indul, és fokozatosan felépíti a szolgáltatásokat. Ez a sorozat ilyen lesz. A sorozat első üzenetében egy minimális alkalmazást állítunk fel a Web Push támogatással, hogy bemutassuk, hogyan lehet elindítani és futtatni. A következő részekben improvizáljuk a felhasználói élményt, és további funkciókat adunk hozzá.

Mielőtt tovább folytatnánk, olvassa el ezt a bejegyzést, hogy megértse a technológia működését. Ha kevés az ideje, itt van egy tömör változat -

  • A Javascript egyetlen menetes. Ez azt jelenti, hogy amikor egy webhely betöltődik, a fő szál mindig a felhasználói interakciók megjelenítésében és kezelésében foglalt el. Ez azonban korlátozza a felhasználói élményt, amelyet a felhasználók számára nyújthatunk. Szükség volt olyan szálakra, amelyek a háttérben futhatnak, anélkül hogy megzavarnák a felhasználói felületet.
  • Webes dolgozókat fejlesztettek ki ennek a követelménynek a teljesítésére.
  • A szolgáltató munkatársak egyfajta webes munkatársak, akiknek segítségével a böngészőt arra utasíthatjuk, hogy hajtson végre bizonyos konkrét háttérfeladatokat.
  • Az egyik elvégzendő feladat a kiszolgáló által küldött push értesítések meghallgatása, amelyeket azután a felhasználó számára meg lehet jeleníteni.
  • A Chrome úttörő támogatást nyújtott ehhez a szolgáltatáshoz. A Firefox már magában foglalja azt.

Tehát a WebPush ezen alapvető ismereteivel együtt merüljünk bele a kódba.

Hősünk - a szervizmunkás

Először nézzük meg, hogy néz ki egy szolgáltató js fájl. Side-note - átvettem a Google Codelabs projektben használt szkripteket, és úgy módosítottam, hogy csak az egyszerű demo számára elengedhetetlen maradjanak.

A kódnak könnyen érthetőnek kell lennie bárki számára, aki alapvető javascript ismeretekkel rendelkezik. A fenti kód fő szokatlan jellemzője az ön kulcsszó. Ez egy hivatkozás a ServiceWorkerGlobalScope-ra, amely egy felület, amely a szolgáltató munkatársait képviseli. Mivel a szolgáltatónak nincs böngészési környezete, ez az ön hivatkozás biztosítja a felülettel a különféle funkciókat, amelyeket általában az ablakobjektum biztosít a böngészési környezetben. Csakúgy, mint a window.addEventListener, itt a szolgáltató eseménykezelőit az self.addEventListener használatával határozzuk meg.

A fenti kódban felsoroltuk 3 eseménykezelőt. A telepítést és az aktiválást kezelõk csak eseményeket naplóznak hibakeresési célokra. A push eseménykezelő szintén egyszerűen érthető. Olvassa be az eseményhez elküldött szöveges adatokat, ellenőrzi, hogy JSON formátumú-e, és ha igen, akkor kibont egy címet és törzset belőle. Ha nem JSON formátumban van, akkor csak azt feltételezi, hogy a teljes karakterláncot fogja használni törzsként, a cím beállítása "Untitled". Mint az alábbiakban látni fogjuk, ez segít a szolgáltatás munkatársainak hibakeresésében az ügyfél krómfejlesztő eszközeiben.

Szolgáltató regisztrálása

A fenti szolgáltatót a weboldalnak regisztrálnia kell, hogy a böngésző tudjon róla. Itt van a regisztrációs szkript, amelyet használni fogunk - register_service_worker.js

Az utolsó funkció - registerServiceWorker - a fő funkció, amelyre felhívják a szolgáltató regisztrálását. 3 érvet fogad el

  1. serviceWorkerUrl - Az URL, amelyet a böngésző felhasználhat a szolgáltató betöltésére. Esetünkben a js szolgáltatót a lombik alkalmazás statikus mappájába helyezzük, és az URL tehát /static/service_worker.js lesz.
  2. Az alkalmazáskiszolgáló nyilvános kulcsa - A második argumentum a hüvelyk nyilvános kulcs. Ez a nyilvános kulcs - a magánkulcs-pár pár nyilvános kulcs-összetevője, amelyet a nyomtatószerver és az ügyfélen futó push szolgáltatás közötti kommunikáció biztonságos engedélyezésére használnak. A mechanizmust itt részletesebben ismertetjük.
  3. apiEndpoint - végül a harmadik argumentum az api végpont, amelyet az ügyfelek által generált push előfizetések mentésére használunk. Példánkban meghatározunk egy végpontot / api / push-előfizetést, amely ezt a munkát végzi.

A registerServiceWorker függvény felhívja az subscribeUser függvényt, amely viszont meghívja az swRegistration.pushManager.subscribe módszert, amely létrehozza az egyedi végpontot, amelyet a push kiszolgáló használ push értesítések küldésére az ügyfél számára. A .subscribe funkcióhívás mellékhatása az, hogy engedélyt kér a felhasználótól a push értesítések megjelenítéséhez, ha a felhasználó még nem engedélyezi.

Ez elegendő ennek az egyszerű példának. A jó felhasználói élmény megköveteli azonban, hogy ellenőrizzük, mikor és hogyan jeleníti meg a kérés riasztást a böngésző. Ezt valóban meg lehet tenni az itt leírt Notification.requestPermission () módszer használatával. De a rövidség kedvéért, hagyjuk ezt az oktatóanyag hatályát kívül, mivel a sorozat első hozzászólásának elsődleges célja az, hogy a push értesítéseket a lehető legkevesebb erőfeszítéssel működtesse.

Most az swRegistration.pushManager.subscribe függvényhívás által generált Push Subscription json így néz ki:

Ezt a json fájlt úgy kell tárolni, hogy a szerver később elküldje a kívánt push értesítést erre a címre. Ezt az updateSubscriptionOnServer függvény hajtja végre, amely az előfizetési jsont az api végponthoz továbbítja, amelyet alább ismertetünk.

Az alkalmazás felépítése

Most, hogy áttekintettük mind a szolgáltató szkriptet, mind a szkript regisztrálásához szükséges szkriptet, megkezdhetjük a szerver felépítésének megvitatását, amelyet a html oldalak és az api végpontok kiszolgálására használunk.

Egy egyszerű Flask szervert építünk háttérként, és úgy konfiguráljuk, hogy egy egyszerű webhelyet kiszolgáljon egy szerviz munkavállalói fájllal, amely Web Push támogatást nyújthat. A kód elérhető ebben a repo-ban. A sorozat első első üzenetében használt alkalmazás a basic_functionality nevű mappában található

Az alkalmazás felépítése így történik

├── app.py ├── példány └── └── application.cfg.py ├── követelmények.txt ├── statikus │ regisztráció_szolgáltatás_munka.js js │ szolgáltatás_munka.js ├── sablonok │ ─ admin.html └── └── index.html └── webpush_handler.py

A példánymappa hiányzik, ha a github repóját klónozza. Ez egy olyan mappa, amelyet nem a verzió elkötelezettségének tekintenek, mivel tartalmazni fogja a titkos kulcsokat (az alábbiakban magyarázzuk meg)

Mielőtt ezeket a fájlokat egyenként áttekintettük, először nézzük meg, hogyan készíthetjük elő a környezetet

A virtualenv beállítása és a követelmények telepítése

A virtualenvwrapper segítségével beállíthatjuk a python környezetet az alkalmazás futtatásához. Hozzon létre egy ilyen virtualenvet

mkvirtualenv -p python3 simple_webpush

És aktív virtualenv esetén telepítse a követelményeket a pip install -r rights.txt fájl használatával. További részletekért tekintse meg a virtualenv és a virtualenvwrapper dokumentumait.

A beállított környezettel megkezdhetjük a szerver kódjának felülvizsgálatát.

Fő szerver modul - app.py

Az app.py teljes kódja itt érhető el. Ebben a példában egy egyszerű Flask alkalmazásmintát használunk. Ha még nem ismeri a Flask-ot, akkor először segítséget nyújt ennek a gyorsindítási útmutatónak a átvitele. Vegye figyelembe, hogy ez az egyszerű alkalmazásstruktúra csak fejlesztési célokra használható. Ha az alkalmazást a termelésbe kívánjuk telepíteni, akkor méretezhetőbb architektúrát kell használnunk. De ez kívül esik ezen első hozzászólás körén.

Most olvassa át az app.py kódját szakaszonként.

a lombik importálásából Lombik, render_template, kérés, jsonify a flask_sqlalchemy importból SQLAlchemy from webpush_handler import trigger_push_notifications_for_subscriptions
app = Lombik (__ név__, példány_relatív_config = True) app.config.from_pyfile ('application.cfg.py')

Alapvető lombik és sqlalchemy modulokat importálunk. Olyan módszert importálunk, amelyet felhasználni fog a push értesítések elindítására (az alábbiakban tárgyaljuk)

Az alkalmazást az True True értékre állított példa_relatív_konfiguráció segítségével hozza létre. Ez lehetővé teszi a titkos konfigurációs információk meghatározását a példánynak nevezett mappában lévő fájlban, amelyet a forrásvezérléstől távol lehet tartani. A következő sor arra utasítja az alkalmazást, hogy töltse be a konfigurációt az application.cfg.py nevű fájlból, amely várhatóan a példánymappában található. Tehát csak hozzon létre egy példány nevű mappát, és hozzon létre ott egy application.cfg.py nevű fájlt. Ide hozzáadjuk a webes értesítések küldéséhez szükséges nyilvános és magánkulcsokat.

Így néz ki a példány / application.cfg.py

VAPID_PUBLIC_KEY = "BBBAASD # DFDFFFFFFFFFFFFFFFFFFFFFFF" 
VAPID_PRIVATE_KEY = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" 
VAPID_CLAIM_EMAIL = "[e-mail védett]"

E nyilvános kulcs-magánkulcs-pár létrehozásához használja ezt a webhelyet - https://web-push-codelab.glitch.me/ Alternatív megoldásként használhatja ezt az npm parancssori segédprogramot is - web-push.

Az app.py következő szakasza az adatbázis réteggel foglalkozik. Az alkalmazásnak adatbázis-kapcsolatra van szüksége a böngésző által generált push előfizetési információk tárolásához. A Flask esetében általában az SQLAlchemy-t használjuk az adatbázis ORM rétegként, a FlaskSQLAlchemy-t pedig linker könyvtárként. Dokumentációira itt és itt hivatkozhat, ha nem ismeri.

app.config ['SQLALCHEMY_DATABASE_URI'] = "sqlite: //" 
db = SQLAlchemy (alkalmazás) 
osztály PushSubscription (db.Model): id = db.Oszlop (db.Integer, elsődleges_kulcs = Igaz, egyedi = Igaz) subscription_json = db.Oszlop (db.Text, nullable = False)
db.create_all ()

A fenti szakaszban a következőket tettem

  1. Az sqlite: // adatbázis-kapcsolati karakterlánc utasítja az SQLAlchemy-t egy memóriában lévő sqlite-adatbázis használatára. Mivel a memóriában van, nem tartós, és az információ el fog veszni, ha a kiszolgáló folyamatát leállítják. De ez elegendő ennek az egyszerű bemutatónak.
  2. A következő sorban inicializáltuk a db kezelőt, majd meghatároztuk a PushSubscription nevű modellt, amelyet az előfizetési információk tárolására használunk. Röviden áttekintjük e json szerkezetét.
  3. A következő db.create_all () sor gondoskodik az adatbázis táblák létrehozásáról - ebben az esetben csak egy tábla, a push_subscription nevű tábla.

A beállított adatbázis után tovább folytathatjuk a szükséges URL-végpontok regisztrálását. Az első útvonal a home_page megjeleníti az index.html sablont.

@ app.route ("/") def home_page (): return render_template ("index.html")

A fent leírt index.html egyszerűen csak minimális sablon lehet, amely betölti a korábban leírt register_service_worker.js szkriptet, majd meghívja a parancsfájlban meghatározott registerServiceWorker funkciót. A Flask előírása szerint ezt a `sablonok` mappába helyezzük.

Mind a js fájlokat a statikus mappába helyeztem, és a register_service_worker.js szkriptet közvetlenül a HTML-be töltöttük. Ez viszont gondoskodik a szolgáltató betöltéséről az első érvként átadott url használatával. A második érv állítólag a nyilvános kulcs, amint azt a regisztrációs szkript áttekintésekor korábban tárgyaltuk. A merev kódolás helyett egy konfigurációs változó segítségével hivatkozunk rá. A Flask gondoskodik arról, hogy ezt a változót azért töltse be, amelyet az / application.cfg.py fájlt korábban megadtunk. És a harmadik érv állítólag az api végpont, amelyre a regisztrációs szkript feltölti az subscription_json fájlt. Az alábbiak szerint definiáljuk az app.py-ben

Mint látható, a fenti api végpont először ellenőrzi, hogy van-e már megfelelő PushSubscription objektum ugyanazzal az subscription_json-nal, és ha igen, akkor visszaküldi azt. Tehát, amikor újratöltjük az oldalt, még akkor is, ha a böngésző ugyanazt az subscription_json-t küldi újra, mert a registerServiceWorker funkciót újra meghívják, az nem okoz hibát a kiszolgálón. Ha viszont nincs megfelelő subscription_json, akkor új bejegyzés jön létre, és visszatér a böngészőbe.

Az eddig elvégzett beállítás elegendő annak ellenőrzéséhez, hogy a szolgáltató dolgozik-e a várt módon. A Chrome fejlesztőeszközei olyan eszközökkel rendelkeznek, amelyek lehetővé teszik a szolgáltató dolgozók kipróbálását a klienstől. Tehát tegyük ezt először, mielőtt megtudná, hogyan küldje el a push értesítéseket a szerverről.

Az ügyféloldali funkciók tesztelése

A kiszolgálót először a flask run paranccsal indítjuk

Amint a szerver elindul, nyissa meg a localhost: 5000-et a böngészőben. Tartsa nyitva a fejlesztői eszközöket oldalán. Ha még nem tette meg ezt, akkor a Chrome menü „További eszközök” szakaszában érhető el. Vagy nyomja meg a Ctrl + Shift + I billentyűket. Miután a webhely betöltődött, megjelenik egy párbeszédpanel, amely értesítési engedélyeket kér. Kattintson az Engedélyezés gombra.

Az „Engedélyezés” gombra kattintva, ha megvizsgáljuk a Hálózat fület a Fejlesztői eszközökben, láthatjuk, hogy egy POST-kérés érkezik az API végponthoz.

A válaszban láthatjuk az előfizetés részleteit.

Most, hogy a szolgáltató regisztrálása megtörtént, próbáljuk ki az értesítőkezelő kódját. A fejlesztői eszközökben kattintson az Alkalmazás fülre, majd az oldalsó menüben kattintson az Alkalmazás -> ServiceWorkers szakaszra.

Megmutatja a regisztrált szolgáltatót a localhost oldalon. Az állapotnak aktívnak és futónak kell lennie. Most kipróbálhatjuk, hogy ez a szolgáltató a várt módon működik-e az ügyfél oldalon, maga a devtools felület használatával. Írjon be néhány karakterláncot a Push feliratú mezőbe, majd kattintson a Push gombra. Az oldalán azonnal megjelenjen egy push értesítés felbukkanó képernyő. A cím „Untitled” néven jelenik meg, mert így kódoltuk (ellenőrizze a fenti service_worker.js kódot)

Kipróbálhatjuk azt is, hogy a service_worker hogyan jeleníti meg az értesítést, ha azt a json formátumban küldjük el, amelyet a szolgáltató kezelésére kódoltunk.

Így ellenőriztük, hogy a szolgáltató értesítőkezelője a várt módon működik-e. A következő lépés a kiszolgáló beállításának végigvitele a push értesítések küldéséhez

Szerverkód az internetes push értesítések küldéséhez

Felállítunk egy egyszerű admin oldalt a push értesítések küldésére. A megfelelő admin irányítópulthoz felhasználói hitelesítés és engedély szükséges. De ezt a sorozat következő hozzászólásaira hagyjuk. Itt csak az értesítések küldéséhez nélkülözhetetlen kódra összpontosítunk.

Először így definiáljuk az admin oldalt az app.py fájlban

@ app.route ("/ admin") def admin_page (): return render_template ("admin.html")

A html meghatározása az alábbiak szerint történik, egy egyszerű űrlap segítségével, amely lehetővé teszi a push üzenet címének és szövegének beírását és elküldését.

Beküldéskor eléri az api végpontot, amelyet a következőképpen határoz meg. Ez a végpont az trigger_push_notifications_for_subscriptions függvényt használja az értesítés küldésére az összes előfizető számára (esetünkben csak egy)

A trigger_push_notifications_for_subscriptions a webpush_handler.py fájlban található, amelyet már az app.py-ben importáltunk

Ez egy olyan funkció egyenes hívása, amelyet a pywebpush könyvtár határoz meg, amelyet már telepítettünk a követelmények részeként. Aláírjuk azt a rejtett magánkulccsal, amelyet átmásoltunk a példányra / application.cfg.py. Mivel az ügyfél már ismeri a nyilvános kulcsot, képes lesz ellenőrizni, hogy a push üzenet csak az engedélyezett szerverről érkezik-e.

Az admin űrlap kipróbálása push értesítések küldésére

Ennek a funkciónak a teszteléséhez keresse fel a localhost webhelyet: 5000 / admin Itt, ha kitöltjük a címet és a szöveget, és elküldjük, láthatjuk az ilyen push értesítést:

Ha olyan értesítést látsz, mint fentebb, akkor gratulálunk, hogy sikeresen felépített egy egyszerű weboldalt egy nagyon egyszerű web-push értesítési támogatással.

Következtetés

A fenti oktatóanyagban áttekintettük, hogyan lehet egy egyszerű alkalmazást létrehozni a push értesítések támogatásával. Folytathatjuk a szolgáltatások építését ezen felül, az alábbiak szerint

  1. A push értesítőkezelő fejlesztése az ügyféloldalon - a Notification.requestPermission () metódus megvalósításával, további lehetőségek hozzáadásával az értesítés megjelenésének és viselkedésének ellenőrzéséhez, a képek támogatásához stb.
  2. Az alkalmazás szerkezetének módosítása, hogy méretezhetőbbé és készen álljon a telepítésre
  3. Használjon állandó adatbázist a push előfizetések tárolásához
  4. Végezzen el felhasználói hitelesítést és engedélyezést, hogy az adminisztrációs űrlap csak bizonyos felhasználók számára nyitható meg.
  5. Támogatás a felhasználói szegmentáláshoz a háttérrendszeren, hogy az értesítéseket elküldhessük egy meghatározott célszegmensre

Ezeket a funkciókat mind a sorozat következő hozzászólásaiban elkészítjük.

Eredetileg a https://techonometrics.com oldalon, 2020. február 8-án tették közzé.