WebPush

TsgcHTMLWebPush: Web Push per un browser che non è in esecuzione o non è sulla tua pagina, in Delphi, C++ Builder e .NET. Disponibile solo nelle edizioni Enterprise e All-Access.

TsgcHTMLWebPush

Web Push raggiunge un utente il cui browser è chiuso o mostra un’altra pagina. La pagina crea una sottoscrizione, la tua applicazione la memorizza tramite tre eventi e una sola chiamata a Send consegna la notifica. Disponibile solo nelle edizioni Enterprise e All-Access.

Classe del componente

TsgcHTMLWebPush (unit sgcHTML_WebPush)

Renderizza

Nessun markup: messaggi push cifrati inviati al browser

Linguaggi

Delphi, C++ Builder, .NET

Genera le chiavi, memorizza le sottoscrizioni, invia

Genera una sola volta una coppia di chiavi VAPID e conservala. Assegna la coppia e un Subject, gestisci gli eventi di archiviazione, imposta WebPush sull’engine e WebPushEnabled sul suo template, quindi chiama 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>

Proprietà e metodi principali

I membri che utilizzerai più spesso.

Edizioni

Web Push è disponibile solo nelle edizioni Enterprise e All-Access. L’unit compila quando è definito SGC_WEBPUSH, cosa che sgcVer.inc imposta per queste due edizioni, e richiede anche sgcHTML stesso, che si vende indipendentemente. L’inbox delle notifiche e la tabella delle preferenze fanno parte di sgcHTML e non lo richiedono: lo richiede solo il canale push.

Chiavi VAPID

GenerateVAPIDKeys è un metodo di classe che restituisce una nuova coppia: la metà pubblica è la chiave del server applicativo in base64url con cui il browser si sottoscrive, la metà privata una chiave EC in PEM. Assegnale a VAPIDPublicKey e VAPIDPrivateKey. Subject è il contatto VAPID, un URI mailto: o https:. La build Delphi standard carica OpenSSL 3.x per la crittografia e seleziona da sola quella API; la versione .NET usa crittografia gestita e non richiede OpenSSL.

Eventi di archiviazione

Il componente non conserva alcuna sottoscrizione propria. OnSaveSubscription(aUserID, aEndpoint, aP256dh, aAuth) ne memorizza una, OnLoadSubscriptions(aUserID, aList) riempie aList con un Add(endpoint, p256dh, auth) per ogni sottoscrizione memorizzata dell’utente, e OnDeleteSubscription(aUserID, aEndpoint) ne rimuove una. Ogni voce è un TsgcHTMLWebPushSubscription.

Invio

Send(aUserID, aTitle, aBody, aURL, aIcon, aTag, aTTL, aUrgency) cifra una notifica per ogni sottoscrizione memorizzata dell’utente (RFC 8291) e la invia con POST al servizio push con una firma VAPID (RFC 8292). Restituisce il numero di sottoscrizioni a cui ha consegnato, oppure 0 quando Enabled è False. Il mittente, TsgcHTMLWebPushClient, riusa TsgcHTTP_API_WebPush_Client.

Time to live e urgenza

TTL vale per impostazione predefinita 2419200 secondi (28 giorni) e Urgency è vuoto, il che non invia alcun header di urgenza. Passa aTTL o aUrgency a Send per sostituire l’uno o l’altro per una singola notifica.

Invii scaduti e falliti

Quando un servizio push risponde 404 o 410, scatta OnSubscriptionExpired(aUserID, aEndpoint, aStatusCode) così puoi eliminare la sottoscrizione. Qualsiasi altro errore genera OnSendError(aUserID, aEndpoint, E) e le sottoscrizioni rimanenti vengono comunque provate.

Endpoint di sottoscrizione

Una volta assegnato il componente all’engine, un POST a SubscribeEndpoint (/push/subscribe) o UnsubscribeEndpoint (/push/unsubscribe) riceve risposta automaticamente: 204 se gestito, 400 per una sottoscrizione non valida, 403 quando non si risolve alcun utente, 413 oltre 64 KB. Chiama tu stesso HandleSubscribe(aJSON, aUserID) e HandleUnsubscribe per instradare i POST a modo tuo.

Chi sta effettuando la sottoscrizione

L’utente non viene mai letto da ciò che il browser invia. Con un TsgcHTMLAuth sull’engine è l’utente del cookie di sessione, e il token CSRF è obbligatorio. Senza, OnResolveUser(aCookieHeader, aHeaders, aBody, aUserID, aAllowed) risponde con il tuo id utente oppure rifiuta. Se non c’è né l’uno né l’altro, la richiesta riceve 403.

Nella pagina

Con Template.WebPushEnabled attivo, l’engine copia la chiave pubblica e gli endpoint nel template, serve il service worker in ServiceWorkerPath e la pagina include lo script di sottoscrizione. Inserisci <button data-sgc-webpush> nella pagina in modo che la richiesta di permesso parta da un clic; data-sgc-webpush="unsubscribe" lo disattiva. I browser richiedono https, oppure localhost durante lo sviluppo.

Pagina o push

TsgcHTMLComponent_Notification sceglie tra i due. Assegna Presence e WebPush, rispondi a OnGetChannel con ncPush e chiama AddNotification(aUserID, aId, aTitle, aMessage, ...): un utente connesso riceve la notifica nella pagina, un utente non connesso la riceve con un Send, così nessuno viene avvisato due volte. Senza un gestore OnGetChannel non viene mai inviato alcun push.

Continua a esplorare

Guida in lineaRiferimento API completo e guida all’uso per questo componente.
Guida a Web PushCome si combinano le varie parti: sottoscrizioni, VAPID, gli endpoint dell’engine e il componente di notifica.
Tutti i componenti sgcHTMLEsplora la matrice completa delle funzionalità di oltre 80 componenti.
Scarica la Prova GratuitaLa prova di 30 giorni include i progetti demo 60.HTML, tra cui 17.FieldService, che usa Web Push.
PrezziLicenze Single, Team e Site con codice sorgente completo.
La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Pronto a Iniziare?

Scarica la versione di prova gratuita e inizia a creare interfacce web in Delphi, C++ Builder e .NET.