WebPush
TsgcHTMLWebPush : Web Push pour un navigateur qui n'est pas en cours d'exécution ou qui n'affiche pas votre page, en Delphi, C++ Builder et .NET. Disponible uniquement dans les éditions Enterprise et All-Access.
TsgcHTMLWebPush : Web Push pour un navigateur qui n'est pas en cours d'exécution ou qui n'affiche pas votre page, en Delphi, C++ Builder et .NET. Disponible uniquement dans les éditions Enterprise et All-Access.
Web Push atteint un utilisateur dont le navigateur est fermé ou affiche une autre page. La page s'abonne, votre application stocke l'abonnement via trois événements, et un seul appel à Send livre la notification. Disponible uniquement dans les éditions Enterprise et All-Access.
TsgcHTMLWebPush (unité sgcHTML_WebPush)
Aucun balisage : messages push chiffrés envoyés au navigateur
Delphi, C++ Builder, .NET
Générez une seule fois une paire de clés VAPID et conservez-la. Affectez la paire et un Subject, gérez les événements de stockage, définissez WebPush sur le moteur et WebPushEnabled sur son modèle, puis appelez Send.
// 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>
Les membres que vous utilisez le plus souvent.
Web Push est disponible uniquement dans les éditions Enterprise et All-Access. L'unité se compile lorsque SGC_WEBPUSH est défini, ce que sgcVer.inc fait pour ces deux éditions, et elle nécessite aussi sgcHTML lui-même, qui est vendu indépendamment. La boîte de réception des notifications et la table des préférences font partie de sgcHTML et n'ont pas besoin de Web Push : seul le canal push en a besoin.
GenerateVAPIDKeys est une méthode de classe qui renvoie une nouvelle paire : la moitié publique est la clé de serveur d'application en base64url avec laquelle le navigateur s'abonne, la moitié privée une clé EC au format PEM. Affectez-les à VAPIDPublicKey et VAPIDPrivateKey. Subject est le contact VAPID, une URI mailto: ou https:. La version Delphi standard charge OpenSSL 3.x pour la cryptographie et sélectionne elle-même cette API ; la version .NET utilise la cryptographie managée et n'a pas besoin d'OpenSSL.
Le composant ne conserve aucun abonnement en propre. OnSaveSubscription(aUserID, aEndpoint, aP256dh, aAuth) en stocke un, OnLoadSubscriptions(aUserID, aList) remplit aList avec un Add(endpoint, p256dh, auth) par abonnement stocké de l'utilisateur, et OnDeleteSubscription(aUserID, aEndpoint) en supprime un. Chaque entrée est un TsgcHTMLWebPushSubscription.
Send(aUserID, aTitle, aBody, aURL, aIcon, aTag, aTTL, aUrgency) chiffre une notification par abonnement stocké de l'utilisateur (RFC 8291) et l'envoie en POST au service push avec une signature VAPID (RFC 8292). Elle renvoie le nombre d'abonnements auxquels elle a livré, ou 0 lorsque Enabled vaut False. L'expéditeur, TsgcHTMLWebPushClient, réutilise TsgcHTTP_API_WebPush_Client.
TTL vaut 2419200 secondes (28 jours) par défaut et Urgency est vide, ce qui n'envoie aucun en-tête d'urgence. Passez aTTL ou aUrgency à Send pour remplacer l'un ou l'autre pour une notification.
Lorsqu'un service push répond 404 ou 410, OnSubscriptionExpired(aUserID, aEndpoint, aStatusCode) se déclenche pour que vous puissiez supprimer l'abonnement. Tout autre échec déclenche OnSendError(aUserID, aEndpoint, E) et les abonnements restants sont tout de même essayés.
Une fois le composant affecté au moteur, un POST vers SubscribeEndpoint (/push/subscribe) ou UnsubscribeEndpoint (/push/unsubscribe) est traité pour vous : 204 lorsqu'il est pris en charge, 400 pour un abonnement invalide, 403 lorsqu'aucun utilisateur n'est résolu, 413 au-delà de 64 KB. Appelez vous-même HandleSubscribe(aJSON, aUserID) et HandleUnsubscribe pour acheminer les POST à votre manière.
L'utilisateur n'est jamais lu depuis ce que le navigateur envoie. Avec un TsgcHTMLAuth sur le moteur, c'est l'utilisateur du cookie de session, et le jeton CSRF est requis. Sans lui, OnResolveUser(aCookieHeader, aHeaders, aBody, aUserID, aAllowed) répond avec votre propre identifiant d'utilisateur ou refuse. Sans l'un ni l'autre, la requête reçoit 403.
Avec Template.WebPushEnabled activé, le moteur copie la clé publique et les points de terminaison dans le modèle, sert le service worker sur ServiceWorkerPath et la page embarque le script d'abonnement. Placez <button data-sgc-webpush> dans la page pour que la demande d'autorisation s'exécute depuis un clic ; data-sgc-webpush="unsubscribe" le désactive. Les navigateurs exigent https, ou localhost pendant le développement.
TsgcHTMLComponent_Notification choisit entre les deux. Affectez Presence et WebPush, répondez à OnGetChannel avec ncPush et appelez AddNotification(aUserID, aId, aTitle, aMessage, ...) : un utilisateur connecté reçoit la notification dans la page, un utilisateur non connecté reçoit un Send, de sorte que personne n'est prévenu deux fois. Sans gestionnaire OnGetChannel, rien n'est jamais poussé.
| Aide en ligneRéférence API complète et guide d’utilisation pour ce composant. | Ouvrir | |
| Guide Web PushComment les éléments s'articulent : abonnements, VAPID, points de terminaison du moteur et composant de notification. | Ouvrir | |
| Tous les composants sgcHTMLParcourez la matrice complète des fonctionnalités de plus de 80 composants. | Ouvrir | |
| Télécharger la version d'essai gratuiteLa version d'essai de 30 jours fournit les projets de démonstration 60.HTML, dont 17.FieldService, qui utilise Web Push. | Ouvrir | |
| TarifsLicences Single, Team et Site avec code source complet. | Ouvrir |