WebPush

TsgcHTMLWebPush: Web Push für einen Browser, der nicht läuft oder nicht auf Ihrer Seite ist, in Delphi, C++ Builder und .NET. Nur in den Editionen Enterprise und All-Access verfügbar.

TsgcHTMLWebPush

Web Push erreicht einen Benutzer, dessen Browser geschlossen ist oder eine andere Seite anzeigt. Die Seite abonniert, Ihre Anwendung speichert das Abonnement über drei Ereignisse, und ein Aufruf von Send liefert die Benachrichtigung aus. Nur in den Editionen Enterprise und All-Access verfügbar.

Komponentenklasse

TsgcHTMLWebPush (Unit sgcHTML_WebPush)

Rendert

Kein Markup: verschlüsselte Push-Nachrichten, die an den Browser gesendet werden

Sprachen

Delphi, C++ Builder, .NET

Schlüssel erzeugen, Abonnements speichern, senden

Erzeugen Sie einmal ein VAPID-Schlüsselpaar und bewahren Sie es auf. Weisen Sie das Paar und ein Subject zu, behandeln Sie die Speicherereignisse, setzen Sie WebPush an der Engine und WebPushEnabled an deren Template und rufen Sie dann Send auf.

// Enterprise and All-Access only: compiled when SGC_WEBPUSH is defined
uses
  Data.DB, sgcHTML_WebPush, sgcHTMX_Engine_Server;

var
  vPublic, vPrivate: string;
begin
  // once, then keep both values in your own settings
  TsgcHTMLWebPush.GenerateVAPIDKeys(vPublic, vPrivate);

  FPush := TsgcHTMLWebPush.Create(Self);
  FPush.VAPIDPublicKey := vPublic;
  FPush.VAPIDPrivateKey := vPrivate;
  FPush.Subject := 'mailto:support@example.com';
  FPush.OnSaveSubscription := PushSave;
  FPush.OnLoadSubscriptions := PushLoad;
  FPush.OnDeleteSubscription := PushDelete;
  FPush.OnSubscriptionExpired := PushExpired;
  FPush.Enabled := True;

  // oHTMX is a TsgcHTMX_Engine_Server
  oHTMX.WebPush := FPush;
  oHTMX.Template.WebPushEnabled := True;

  // later, from anywhere in the application
  FPush.Send('u1', 'Order shipped',
    'Order 1042 left the warehouse', '/orders/1042');
end;

// the application owns the storage
procedure TForm1.PushSave(Sender: TObject;
  const aUserID, aEndpoint, aP256dh, aAuth: string);
begin
  SaveSubscription(aUserID, aEndpoint, aP256dh, aAuth);
end;

procedure TForm1.PushLoad(Sender: TObject; const aUserID: string;
  const aList: TsgcHTMLWebPushSubscriptions);
var
  oQuery: TDataSet;
begin
  oQuery := OpenSubscriptions(aUserID);
  try
    // one Add per stored subscription of this user
    while not oQuery.Eof do
    begin
      aList.Add(oQuery.FieldByName('endpoint').AsString,
        oQuery.FieldByName('p256dh').AsString,
        oQuery.FieldByName('auth').AsString);
      oQuery.Next;
    end;
  finally
    oQuery.Free;
  end;
end;

procedure TForm1.PushDelete(Sender: TObject; const aUserID, aEndpoint: string);
begin
  DeleteSubscription(aUserID, aEndpoint);
end;

procedure TForm1.PushExpired(Sender: TObject;
  const aUserID, aEndpoint: string; aStatusCode: Integer);
begin
  // 404 or 410: the push service dropped it for good
  DeleteSubscription(aUserID, aEndpoint);
end;

// in the page, a click starts the permission prompt:
// <button data-sgc-webpush>Enable notifications</button>
// includes: sgcHTML_WebPush.hpp, sgcHTMX_Engine_Server.hpp
// Enterprise and All-Access only: compiled when SGC_WEBPUSH is defined

String vPublic, vPrivate;
// once, then keep both values in your own settings
TsgcHTMLWebPush::GenerateVAPIDKeys(vPublic, vPrivate);

FPush = new TsgcHTMLWebPush(this);
FPush->VAPIDPublicKey = vPublic;
FPush->VAPIDPrivateKey = vPrivate;
FPush->Subject = "mailto:support@example.com";
FPush->OnSaveSubscription = PushSave;
FPush->OnLoadSubscriptions = PushLoad;
FPush->OnDeleteSubscription = PushDelete;
FPush->OnSubscriptionExpired = PushExpired;
FPush->Enabled = true;

// oHTMX is a TsgcHTMX_Engine_Server
oHTMX->WebPush = FPush;
oHTMX->Template->WebPushEnabled = true;

// later, from anywhere in the application
FPush->Send("u1", "Order shipped",
  "Order 1042 left the warehouse", "/orders/1042");

// the application owns the storage
void __fastcall TForm1::PushSave(TObject *Sender,
  const UnicodeString aUserID, const UnicodeString aEndpoint,
  const UnicodeString aP256dh, const UnicodeString aAuth)
{
  SaveSubscription(aUserID, aEndpoint, aP256dh, aAuth);
}

void __fastcall TForm1::PushLoad(TObject *Sender, const UnicodeString aUserID,
  TsgcHTMLWebPushSubscriptions *const aList)
{
  // one Add per stored subscription of this user
  for (const TStoredSubscription &row : LoadSubscriptions(aUserID))
    aList->Add(row.Endpoint, row.P256dh, row.Auth);
}

// in the page, a click starts the permission prompt:
// <button data-sgc-webpush>Enable notifications</button>
using esegece.sgcWebSockets;

// once, then keep both values in your own settings
TsgcHTMLWebPush.GenerateVAPIDKeys(out var pub, out var priv);

var push = new TsgcHTMLWebPush();
push.VAPIDPublicKey = pub;
push.VAPIDPrivateKey = priv;
push.Subject = "mailto:support@example.com";

// the application owns the storage
push.OnSaveSubscription += (sender, aUserID, aEndpoint, aP256dh, aAuth) =>
    SaveSubscription(aUserID, aEndpoint, aP256dh, aAuth);
push.OnLoadSubscriptions += (sender, aUserID, aList) =>
{
    // one Add per stored subscription of this user
    foreach (var row in LoadSubscriptions(aUserID))
        aList.Add(row.Endpoint, row.P256dh, row.Auth);
};
push.OnDeleteSubscription += (sender, aUserID, aEndpoint) =>
    DeleteSubscription(aUserID, aEndpoint);
push.OnSubscriptionExpired += (sender, aUserID, aEndpoint, aStatusCode) =>
    DeleteSubscription(aUserID, aEndpoint);   // 404 or 410: gone for good
push.Enabled = true;

// htmx is a TsgcHTMX_Engine_Server
htmx.WebPush = push;
htmx.Template.WebPushEnabled = true;

// later, from anywhere in the application
int delivered = push.Send("u1", "Order shipped",
    "Order 1042 left the warehouse", "/orders/1042");

// in the page, a click starts the permission prompt:
// <button data-sgc-webpush>Enable notifications</button>

Wichtige Eigenschaften & Methoden

Die Member, die Sie am häufigsten verwenden.

Editionen

Web Push ist nur in den Editionen Enterprise und All-Access verfügbar. Die Unit kompiliert, wenn SGC_WEBPUSH definiert ist, was sgcVer.inc für diese beiden Editionen setzt, und sie benötigt außerdem sgcHTML selbst, das unabhängig verkauft wird. Der Benachrichtigungs-Posteingang und die Einstellungstabelle gehören zu sgcHTML und brauchen Web Push nicht, nur der Push-Kanal braucht es.

VAPID-Schlüssel

GenerateVAPIDKeys ist eine Klassenmethode, die ein neues Paar zurückgibt: Die öffentliche Hälfte ist der base64url-kodierte Application-Server-Key, mit dem der Browser das Abonnement anlegt, die private Hälfte ein EC-Schlüssel im PEM-Format. Weisen Sie sie VAPIDPublicKey und VAPIDPrivateKey zu. Subject ist der VAPID-Kontakt, eine URI mit mailto: oder https:. Der Standard-Delphi-Build lädt OpenSSL 3.x für die Kryptografie und wählt diese API selbst aus; die .NET-Portierung verwendet verwaltete Kryptografie und benötigt kein OpenSSL.

Speicherereignisse

Die Komponente speichert selbst keine Abonnements. OnSaveSubscription(aUserID, aEndpoint, aP256dh, aAuth) speichert eines, OnLoadSubscriptions(aUserID, aList) füllt aList mit je einem Add(endpoint, p256dh, auth) pro gespeichertem Abonnement des Benutzers, und OnDeleteSubscription(aUserID, aEndpoint) entfernt eines. Jeder Eintrag ist eine TsgcHTMLWebPushSubscription.

Senden

Send(aUserID, aTitle, aBody, aURL, aIcon, aTag, aTTL, aUrgency) verschlüsselt pro gespeichertem Abonnement des Benutzers eine Benachrichtigung (RFC 8291) und sendet sie per POST mit einer VAPID-Signatur (RFC 8292) an den Push-Dienst. Die Methode gibt zurück, an wie viele Abonnements zugestellt wurde, oder 0, wenn Enabled False ist. Der Sender, TsgcHTMLWebPushClient, verwendet TsgcHTTP_API_WebPush_Client wieder.

Lebensdauer und Dringlichkeit

TTL ist standardmäßig 2419200 Sekunden (28 Tage), und Urgency ist leer, wodurch kein Urgency-Header gesendet wird. Übergeben Sie aTTL oder aUrgency an Send, um eines von beiden für eine einzelne Benachrichtigung zu überschreiben.

Abgelaufene und fehlgeschlagene Sendungen

Antwortet ein Push-Dienst mit 404 oder 410, wird OnSubscriptionExpired(aUserID, aEndpoint, aStatusCode) ausgelöst, damit Sie das Abonnement verwerfen können. Jeder andere Fehler löst OnSendError(aUserID, aEndpoint, E) aus, und die übrigen Abonnements werden trotzdem noch versucht.

Abonnement-Endpunkte

Sobald die Komponente der Engine zugewiesen ist, wird ein POST an SubscribeEndpoint (/push/subscribe) oder UnsubscribeEndpoint (/push/unsubscribe) für Sie beantwortet: 204 bei erfolgreicher Verarbeitung, 400 bei einem ungültigen Abonnement, 403, wenn kein Benutzer ermittelt wird, 413 über 64 KB. Rufen Sie HandleSubscribe(aJSON, aUserID) und HandleUnsubscribe selbst auf, um die POSTs auf Ihre eigene Weise zu routen.

Wer abonniert

Der Benutzer wird nie aus dem gelesen, was der Browser sendet. Mit einem TsgcHTMLAuth an der Engine ist es der Benutzer des Sitzungs-Cookies, und das CSRF-Token ist erforderlich. Ohne ein solches antwortet OnResolveUser(aCookieHeader, aHeaders, aBody, aUserID, aAllowed) mit Ihrer eigenen Benutzer-ID oder lehnt ab. Ohne beides erhält die Anfrage 403.

In der Seite

Ist Template.WebPushEnabled aktiviert, kopiert die Engine den öffentlichen Schlüssel und die Endpunkte in das Template, liefert den Service Worker unter ServiceWorkerPath aus, und die Seite enthält das Abonnement-Skript. Setzen Sie <button data-sgc-webpush> in die Seite, damit die Berechtigungsabfrage durch einen Klick ausgelöst wird; data-sgc-webpush="unsubscribe" schaltet es aus. Browser benötigen https oder, während der Entwicklung, localhost.

Seite oder Push

TsgcHTMLComponent_Notification entscheidet zwischen beiden. Weisen Sie Presence und WebPush zu, beantworten Sie OnGetChannel mit ncPush und rufen Sie AddNotification(aUserID, aId, aTitle, aMessage, ...) auf: Ein verbundener Benutzer erhält die Benachrichtigung in der Seite, ein nicht verbundener Benutzer erhält ein Send, sodass niemand doppelt benachrichtigt wird. Ohne einen OnGetChannel-Handler wird nie etwas gepusht.

Weiter entdecken

Online-HilfeVollständige API-Referenz und Verwendungshandbuch für diese Komponente.
Anleitung zu Web PushWie die Teile zusammenpassen: Abonnements, VAPID, die Engine-Endpunkte und die Benachrichtigungskomponente.
Alle sgcHTML-KomponentenDurchsuchen Sie die vollständige Funktionsmatrix von über 80 Komponenten.
Kostenlose Testversion herunterladenDie 30-Tage-Testversion enthält die 60.HTML-Demoprojekte, darunter 17.FieldService, das Web Push verwendet.
PreiseSingle-, Team- und Site-Lizenzen mit vollständigem Quellcode.
Bestes Preis-Leistungs-Verhältnis: All-AccessAlle eSeGeCe-Produkte, inklusive Premium-Support, ab €1,059 pro Jahr.
All-Access-Preise ansehen

Bereit loszulegen?

Laden Sie die kostenlose Testversion herunter und beginnen Sie, Web-UIs in Delphi, C++ Builder und .NET zu erstellen.