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 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.
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.
TsgcHTMLWebPush (Unit sgcHTML_WebPush)
Kein Markup: verschlüsselte Push-Nachrichten, die an den Browser gesendet werden
Delphi, C++ Builder, .NET
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>
Die Member, die Sie am häufigsten verwenden.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
| Online-HilfeVollständige API-Referenz und Verwendungshandbuch für diese Komponente. | Öffnen | |
| Anleitung zu Web PushWie die Teile zusammenpassen: Abonnements, VAPID, die Engine-Endpunkte und die Benachrichtigungskomponente. | Öffnen | |
| Alle sgcHTML-KomponentenDurchsuchen Sie die vollständige Funktionsmatrix von über 80 Komponenten. | Öffnen | |
| Kostenlose Testversion herunterladenDie 30-Tage-Testversion enthält die 60.HTML-Demoprojekte, darunter 17.FieldService, das Web Push verwendet. | Öffnen | |
| PreiseSingle-, Team- und Site-Lizenzen mit vollständigem Quellcode. | Öffnen |