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 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.

Classe du composant

TsgcHTMLWebPush (unité sgcHTML_WebPush)

Produit

Aucun balisage : messages push chiffrés envoyés au navigateur

Langages

Delphi, C++ Builder, .NET

Générez des clés, stockez les abonnements, envoyez

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>

Propriétés & méthodes clés

Les membres que vous utilisez le plus souvent.

Éditions

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.

Clés VAPID

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.

Événements de stockage

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.

Envoi

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.

Durée de vie et urgence

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.

Envois expirés et échoués

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.

Points de terminaison d'abonnement

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.

Qui s'abonne

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.

Dans la page

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.

Page ou push

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é.

Continuez l'exploration

Aide en ligneRéférence API complète et guide d’utilisation pour ce composant.
Guide Web PushComment les éléments s'articulent : abonnements, VAPID, points de terminaison du moteur et composant de notification.
Tous les composants sgcHTMLParcourez la matrice complète des fonctionnalités de plus de 80 composants.
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.
TarifsLicences Single, Team et Site avec code source complet.
Meilleur rapport qualité-prix : All-AccessTous les produits eSeGeCe, Support Premium inclus, à partir de €1,059/an.
Voir les tarifs All-Access

Prêt à démarrer ?

Téléchargez la version d'essai gratuite et commencez à créer des interfaces web en Delphi, C++ Builder et .NET.